/*
Copyright(c) 2012 Company Name
*/
Ext.define('BISC.model.ImagesModel', {
  extend: 'Ext.data.Model',
  fields: [
    {
      name: 'id'
    },
    {
      name: 'path'
    },
    {
      name: 'folderId'
    },
    {
      name: 'fileType'
    },
    {
      name: 'thumbnail'
    },
    {
      name: 'bisImageId'
    },
    {
      name: 'blackList'
    },
    {
      name: 'online'
    },
    {
      name: 'timestampModified'
    },
    {
      name: 'error',
      value: ''
    }
  ]
});

Ext.define('BISC.store.ImagesStore', {
  extend: 'Ext.data.Store',
  requires: [
    'BISC.model.ImagesModel'
  ],

  constructor: function(cfg) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      autoLoad: true,
      storeId: 'MyJsonPStore',
      model: 'BISC.model.ImagesModel',
      proxy: {
        type: 'jsonp',
        url: 'http://localhost:8888/images/list',
        reader: {
          type: 'json',
          idProperty: 'id',
          root: 'records',
          totalProperty: 'totalCount'
        }
      }
    }, cfg)]);
  }
});

/*
 * File: app/model/PropertiesModel.js
 *
 * This file was generated by Sencha Architect version 2.0.0.
 * http://www.sencha.com/products/architect/
 *
 * This file requires use of the Ext JS 4.0.x library, under independent license.
 * License of Sencha Architect does not include license for Ext JS 4.0.x. For more
 * details see http://www.sencha.com/license or contact license@sencha.com.
 *
 * This file will be auto-generated each and everytime you save your project.
 *
 * Do NOT hand edit this file.
 */

Ext.define('BISC.model.PropertiesModel', {
  extend: 'Ext.data.Model'
});
/*
 * File: app/store/PropertiesStore.js
 *
 * This file was generated by Sencha Architect version 2.0.0.
 * http://www.sencha.com/products/architect/
 *
 * This file requires use of the Ext JS 4.0.x library, under independent license.
 * License of Sencha Architect does not include license for Ext JS 4.0.x. For more
 * details see http://www.sencha.com/license or contact license@sencha.com.
 *
 * This file will be auto-generated each and everytime you save your project.
 *
 * Do NOT hand edit this file.
 */

Ext.define('BISC.store.PropertiesStore', {
  extend: 'Ext.data.Store',
  requires: [
    'BISC.model.PropertiesModel'
  ],

  constructor: function(cfg) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      storeId: 'MyJsonPStore1',
      model: 'BISC.model.PropertiesModel',
      proxy: {
        type: 'jsonp',
        reader: {
          type: 'json'
        }
      }
    }, cfg)]);
  }
});
Ext.define('BISC.model.FolderModel', {
  extend: 'Ext.data.Model',
  fields: [
    {
        name: 'text',
        mapping: 'path',
        convert: function( value, record ) {
            if ( value.charAt(value.length-1) == '/' ) value = value.slice( 0, -1 );
            return value.substr( value.lastIndexOf('/') + 1 );
        }
    },
    {
        name: 'subpath',
        mapping: 'path',
        convert: function( value, record ) {
            if ( value.charAt(value.length-1) == '/' ) value = value.slice( 0, -1 );
            return value.substr( 0, value.lastIndexOf('/') + 1 );
        }
    },
    {
        name: 'path'
    },
    {
        name: 'leaf'
    },
    {
        name: 'expanded'
    },
    {
        name: 'id'
    },
    {
        name: 'sz'
    }
  ]
});

Ext.define('BISC.store.FoldersStore', {
  extend: 'Ext.data.TreeStore',
  requires: [
    'BISC.model.FolderModel'
  ],
  constructor: function(cfg) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      autoLoad: false,
      autoSync: false,
      storeId: 'folderListTreeStore',
      model: 'BISC.model.FolderModel',
      proxy: {
        type: 'jsonp',
        url: 'http://localhost:8888/folders/list',
        reader: {
          type: 'json',
          implicitIncludes: false,
          root: 'records'
        }
      }
    }, cfg)]);
  }
});

Ext.define('BISC.model.FilterModel', {
  extend: 'Ext.data.Model',
  fields: [
    {
        name: 'name'
    },
    {
        name: 'attributes'
    },
    {
        name: 'selects'
    },
    {
        name: 'rejects'
    },
    {
        name: 'monitors'
    },
    {
        name: 'recursive'
    },
    {
        name: 'filterId'
    },
    {
        name: 'data'
    }
  ]
});

Ext.define('BISC.store.FiltersStore', {
  extend: 'Ext.data.Store',
  requires: [
    'BISC.model.FilterModel'
  ],
  constructor: function(cfg) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      autoLoad: true,
      storeId: 'filterstore',
      model: 'BISC.model.FilterModel',
      proxy: {
        type: 'jsonp',
        url: 'http://localhost:8888/listFilters',
        reader: {
          type: 'json',
          implicitIncludes: false,
          root: 'records'
        }
      }
    }, cfg)]);
  }
});

Ext.define('BISC.store.FolderListStore', {
  extend: 'Ext.data.Store',
  requires: [
    'BISC.model.FolderModel'
  ],
  constructor: function( cfg ) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      storeId: 'folderListStore',
      model: 'BISC.model.FolderModel',
      autoLoad: true,
      proxy: {
        type: 'jsonp',
        url: 'http://localhost:8888/monitors/list',
        reader: {
          type: 'json',
          root: 'data',
          totalProperty: 'totalCount'
        }
      }
    }, cfg)]);
  }
});

Ext.define('BISC.model.CategoriesModel', {
  extend: 'Ext.data.Model',

  fields: [
    {
      name: 'bisId'
    },
    {
      name: 'categoryId'
    },
    {
      name: 'title'
    }
  ]
});

Ext.define('BISC.store.CategoriesStore', {
  extend: 'Ext.data.Store',
  requires: [
    'BISC.model.CategoriesModel'
  ],

  constructor: function(cfg) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      autoLoad: true,
      storeId: 'categoriesStore',
      model: 'BISC.model.CategoriesModel',
      proxy: {
        type: 'jsonp',
        extraParams: {
          bisId: 1
        },
        url: 'http://localhost:8888/categories/list',
        reader: {
          type: 'json',
          root: 'records'
        }
      }
    }, cfg)]);
  }
});

Ext.define('BISC.model.AttributesModel', {
  extend: 'Ext.data.Model',

  fields: [
        {
            name: 'attributeId'
        },
        {
            name: 'categoryId'
        },
        {
            name: 'categoryTitle'
        },
        {
            name: 'bisId'
        },
        {
            name: 'title',
            mapping: 'name'
        },
        {
            name: 'leaf',
            defaultValue: true
        },
        {
            name: 'checked',
            defaultValue: null
        },
        {
            name: 'modelClass',
            defaultValue: 'attribute'
        }
  ]
});

Ext.define('BISC.store.AttributesStore', {
  extend: 'Ext.data.Store',
  requires: [
    'BISC.model.AttributesModel'
  ],
  constructor: function(cfg) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      autoLoad: true,
      storeId: 'attributesStore',
      model: 'BISC.model.AttributesModel',
      proxy: {
        type: 'jsonp',
        url: 'http://localhost:8888/attributes/list',
        extraParams: {
            bisId: 1
        },
        reader: {
          type: 'json',
          root: 'records',
          successProperty: 'success',
          totalProperty: 'totalCount'
        }
      }
    }, cfg)]);
  }
});

Ext.define('BISC.model.CattributeModel', {
    extend: 'Ext.data.Model',
    alias: 'model.cattributeModel',

    fields: [
        {
            name: 'attributeId'
        },
        {
            name: 'categoryId'
        },
        {
            name: 'title'
        },
        {
            name: 'name'
        },
        {
            name: 'leaf',
            defaultValue: false
        },
        {
            name: 'checked',
            defaultValue: null
        },
        {
            name: 'modelClass',
            defaultValue: 'category'
        }
    ]
});

Ext.define('BISC.store.CategoryTreeStore', {
    extend: 'Ext.data.TreeStore',
    requires: [
        'BISC.model.CattributeModel'
    ],
    constructor: function(cfg) {
        var me = this;
        cfg = cfg || {};
        me.callParent([Ext.apply({
            storeId: 'categoryTreeStore',
            model: 'BISC.model.CattributeModel',
            proxy: {
                type: 'jsonp',
                url: 'http://localhost:8888/categories/list',
                reader: {
                    type: 'json',
                    root: 'records',
                    successProperty: 'success'
                }
            }
        }, cfg)]);
    }
});

Ext.define('BISC.model.ServerModel', {
  extend: 'Ext.data.Model',
  fields: [
    {
        name: 'id'
    },
    {
        name: 'url'
    },
    {
        name: 'key'
    },
    {
        name: 'active'
    },
    {
        name: 'name'
    },
    {
        name: 'description'
    },
    {
        name: 'path'
    }
  ]
});

Ext.define('BISC.store.ServerStore', {
  extend: 'Ext.data.Store',
  requires: [
    'BISC.model.ServerModel'
  ],
  constructor: function(cfg) {
    var me = this;
    cfg = cfg || {};
    me.callParent([Ext.apply({
      autoLoad: true,
      storeId: 'serverstore',
      model: 'BISC.model.ServerModel',
      proxy: {
        type: 'jsonp',
        url: 'http://localhost:8888/listServers',
        reader: {
          type: 'json',
          implicitIncludes: false,
          root: 'records'
        }
      }
    }, cfg)]);
  }
});

Ext.define('BISC.view.CtxMnuFilter', {
    extend: 'Ext.menu.Menu',
    scope: this,
    listeners: {
        click: function( menu, item ) {
            switch( item.identifier ) {
                case 'update':
                    this.update();
                    break;
                case 'delete':
                    Ext.Msg.confirm('Remove Filter', 'Are you sure you want remove "' + this.record.data.name + '"?', function( btn, nothing, item ) {
                        if ( btn == 'yes' ) {
                            this.remove();
                        }
                    }, this);
                    break;
            }
        }
    },
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    text: 'Edit',
                    iconCls: 'icon_editFilter',
                    identifier: 'update'
                },
                {
                    text: 'Remove',
                    iconCls: 'icon_removeFilter',
                    identifier: 'delete'
                }
            ]
        });
        me.callParent(arguments);
    },
    remove: function() {
        Ext.Ajax.request({
            url: 'http://localhost:8888/removeFilter?filterId=' + this.record.data.filterId,
            success: function() { Ext.getCmp('filtersGrid').getStore().load() }
        });
    },
    update: function() {
        Ext.create('Ext.window.Window', {
            title: 'Edit Filter ' + this.record.data.name,
            iconCls: 'icon_editFilter',
            modal: true,
            height: 500,
            width: 800,
            layout: 'fit',
            items: [
                Ext.create('widget.formcreatefilter', {
                    filter: this.record
                })
            ]
        }).show();
    }
});

Ext.define('BISC.view.FilterManagerRulesInput', {
    extend: 'Ext.form.Panel',
    alias: ['widget.filtermanagerrulesinput'],
    id: 'formAddFilterComponents',
    title: 'Filters',
    border: false,
    bodyPadding: 10,
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'panel',
                    border: false,
                    id: 'filterTokensPanel',
                    data: me.mainForm.filter.filters,
                    tpl: new Ext.XTemplate('<tpl for=".">' +
                                    '<div>' +
                                        '<button class="removeTokenBtn" filter-id="{id}">Remove</button>{text}' +
                                    '</div>' +
                                '</tpl>'
                    ),
                    scope: me,
                    listeners: {
                        afterrender: function() {
                            me.addDataviewItemListeners();
                        }
                    }
                },
                {
                    xtype: 'component',
                    html: 'Automatic attribution only occurs when <span style="font-weight: bold;">all</span> the filters match the image. Filters match all images by default.<br><div id="addCmpError" style="color: red; padding: 5px; font-weight: bold;"></div>'
                },
                {
                    xtype: 'combo',
                    fieldLabel: 'Add filter',
                    queryMode: 'local',
                    displayField: 'value',
                    valueField: 'key',
                    store: Ext.create('Ext.data.Store', {
                        fields: ['key', 'value'],
                        data: [
                            {key: 'keyword', value: 'Keyword'},
                            {key: 'datetime', value: 'Exact Date or Range'}
                        ]
                    }),
                    listeners: {
                        change: function( combo, newVal, oldVal, opts ) {
                            var oldF = Ext.getCmp('addCmp'+oldVal);
                            var newF = Ext.getCmp('addCmp'+newVal);
                            if ( oldF ) oldF.hide();
                            if ( newF ) newF.show();
                        }
                    }
                },
                {
                    xtype: 'textfield',
                    hidden: true,
                    id: 'addCmpkeyword',
                    fieldLabel: 'Add keyword',
                    enableKeyEvents: true,
                    listeners: {
                        keypress: function( field, e, opts ) {
                            if ( e.keyCode == e.ENTER ) {
                                var value = field.getValue();
                                var tempFilter = {
                                    id: me.mainForm.filter.tempId++,
                                    type: 'keyword',
                                    raw: value,
                                    text: 'Keyword: ' + value
                                };
                                if ( value != '' ) {
                                    if ( me.filterExists( tempFilter ) ) {
                                        Ext.get('addCmpError').update('Filter already added.');
                                    } else {
                                        me.mainForm.filter.filters.push( tempFilter );
                                        Ext.getCmp('filterTokensPanel').update( me.mainForm.filter.filters );
                                        Ext.getCmp('formAddFilterComponents').addDataviewItemListeners();
                                        Ext.get('addCmpError').update('');
                                    }
                                }
                            }
                        }
                    }
                },
                {
                    xtype: 'panel',
                    hidden: true,
                    id: 'addCmpdatetime',
                    singleDate: true,
                    items: [
                        {
                            xtype: 'component',
                            html: 'Add date range'
                        },
                        {
                            xtype: 'combo',
                            id: 'addCmpDateType',
                            queryMode: 'local',
                            displayField: 'value',
                            valueField: 'key',
                            value: 'added',
                            store: Ext.create('Ext.data.Store', {
                                fields: ['key', 'value'],
                                data: [
                                    {key: 'added', value: 'Date Added'},
                                    {key: 'modified', value: 'Date Modified'}
                                ]
                            })
                        },
                        {
                            xtype: 'datefield',
                            id: 'addCmpdatetime1',
                            fieldLabel: 'Exact date'
                        },
                        {
                            xtype: 'checkbox',
                            fieldLabel: 'Use date range?',
                            listeners: {
                                change: function( cb, newVal, oldVal, opts ) {
                                    if ( newVal ) {
                                        Ext.getCmp('addCmpdatetime').singleDate = false;
                                        Ext.getCmp('addCmpdatetime1').setFieldLabel( 'Minimum date' );
                                        Ext.getCmp('addCmpdatetime2').enable();
                                    } else {
                                        Ext.getCmp('addCmpdatetime').singleDate = true;
                                        Ext.getCmp('addCmpdatetime1').setFieldLabel( 'Exact date' );
                                        Ext.getCmp('addCmpdatetime2').disable();
                                    }
                                }
                            }
                        },
                        {
                            xtype: 'datefield',
                            id: 'addCmpdatetime2',
                            fieldLabel: 'Maximum date',
                            disabled: true
                        },
                        {
                            xtype: 'button',
                            text: 'Add Date Filter',
                            scope: me,
                            handler: function() {
                                var tempFilter = {
                                    id: me.mainForm.filter.tempId++,
                                    type: ( Ext.getCmp('addCmpdatetime').singleDate ) ? 'date' : 'daterange',
                                    type2: Ext.getCmp('addCmpDateType').getValue(),
                                    raw: Ext.Date.format( Ext.getCmp('addCmpdatetime1').getValue(), 'm-d-Y'),
                                    raw2: Ext.Date.format( Ext.getCmp('addCmpdatetime2').getValue(), 'm-d-Y'),
                                    text: ''
                                };
                                tempFilter.text = me.parseTokenRawValue( tempFilter );

                                if ( tempFilter.type == 'date' ) {
                                    if ( tempFilter.raw == '' ) {
                                        Ext.get('addCmpError').update('Please enter a date.');
                                    } else {
                                        if ( me.filterExists( tempFilter ) ) {
                                            Ext.get('addCmpError').update('Date already exists.');
                                        } else {
                                            me.mainForm.filter.filters.push( tempFilter );
                                            Ext.getCmp('filterTokensPanel').update( me.mainForm.filter.filters );
                                            Ext.getCmp('formAddFilterComponents').addDataviewItemListeners();
                                            Ext.get('addCmpError').update('');
                                        }
                                    }
                                } else {
                                    if ( tempFilter.raw == '' || tempFilter.raw2 == '' ) {
                                        Ext.get('addCmpError').update('Please enter a minimum and maximum date.');
                                        return;
                                    }
                                    if ( tempFilter.raw > tempFilter.raw2 ) {
                                        Ext.get('addCmpError').update('Minimum date must be lower than the maximum date.');
                                    } else {
                                        if ( me.filterExists( tempFilter ) ) {
                                            Ext.get('addCmpError').update('Date range already exists.');
                                        } else {
                                            me.mainForm.filter.filters.push( tempFilter );
                                            Ext.getCmp('filterTokensPanel').update( me.mainForm.filter.filters );
                                            Ext.getCmp('formAddFilterComponents').addDataviewItemListeners();
                                            Ext.get('addCmpError').update('');
                                        }
                                    }
                                }
                            }
                        }
                    ]
                }
            ]
        });

        me.callParent(arguments);
    },
    filterExists: function( newToken ) {
        var flag = false;
        Ext.each( this.mainForm.filter.filters, function( filter ) {
            if ( newToken.type == 'daterange' ) {
                if ( filter.raw == newToken.raw && filter.raw2 == newToken.raw2 ) flag = true;
            } else {
                if ( filter.raw == newToken.raw ) flag = true;
            }
        });
        return flag;
    },
    parseTokenRawValue: function( rule ) {
        if ( rule.type == 'date' ) {
            return 'Date ' + rule.type2 + ' is ' + rule.raw;
        }
        if ( rule.type == 'daterange' ) {
            return 'Date ' + rule.type2 + ' is between ' + rule.raw + ' and ' + rule.raw2;
        }
        if ( rule.type == 'keyword' ) {
            return 'Keyword: ' + rule.raw;
        }
    },
    addDataviewItemListeners: function() {
        Ext.getCmp('filterTokensPanel').getEl().select('.removeTokenBtn').each( function( el ) {
            el.on( 'click', function( e, el, opts ) {
                var filterId = el.getAttribute( 'filter-id' );
                var filters = Ext.getCmp('createFilterPanel').filter.filters;
                Ext.each( filters, function( filter ) {
                    if ( filter.id == filterId ) {
                        filters.splice( filters.indexOf( filter ), 1 );
                        Ext.getCmp('filterTokensPanel').update( filters );
                        Ext.getCmp('formAddFilterComponents').addDataviewItemListeners();
                        return;
                    }
                });
            });
        });
    }
});

Ext.define('BISC.view.FilterManagerAttributesInput', {
    extend: 'Ext.form.Panel',
    alias: ['widget.filtermanagerattributesinput'],
    id: 'formAddFilterAttribute',
    title: 'Attributes',
    bodyPadding: 10,
    border: false,
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'panel',
                    border: false,
                    id: 'filterAttributesPanel',
                    data: me.mainForm.filter.attributes,
                    tpl: new Ext.XTemplate('<tpl for=".">' +
                                '<div>' +
                                    '<button class="removeAttributeBtn" attribute-id="{id}">Remove</button>' +
                                    '<button class="toggleAdditiveBtn" attribute-id="{id}" style="color:{[this.getColor(values.isAdd)]};">{[this.getText(values.isAdd)]}</button>' +
                                    '<input class="overrideCbx" checked="{[this.isChecked(values.isOverride)]}" attribute-id="{id}" type="checkbox"> ' +
                                    '{[this.printMainText(values)]}' +
                                '</div>' +
                            '</tpl>', {
                                isChecked: function( isOverride ) {
                                    if ( isOverride ) return 'checked';
                                    return '';
                                },
                                getColor: function( isAdd ) {
                                    if ( isAdd ) return 'green';
                                    return 'red';
                                },
                                getText: function( isAdd ) {
                                    if ( isAdd ) return '+';
                                    return '-';
                                },
                                printMainText: function( values ) {
                                    var string = values.value;
                                    if ( values.fields.length > 0 ) {

                                        if ( typeof values.format == 'undefined' ) {
                                            // path
                                            if ( values.value.charAt( values.value.length-1 ) != '/' ) string += '/';
                                            Ext.each( values.fields, function( field ) {
                                                string += '<span style="font-weight:bold">' + field.text + '</span>/';
                                            });
                                            string += 'image.ext';
                                        } else {
                                            // filename
                                            var formatString = '';
                                            switch ( values.format ) {
                                                case 'upper':
                                                    formatString = 'uppercase';
                                                    break;
                                                case 'lower':
                                                    formatString = 'lowercase';
                                                    break;
                                                case 'ucfirst':
                                                    formatString = 'first character uppercase only';
                                                    break;
                                            }
                                            string = '<span style="font-weight:bold">image.ext</span> > <span style="font-weight:bold">' + values.value + '</span> > ' + '<span style="font-weight:bold">' + values.fields[0].text + '</span> as ' + formatString + '.';
                                        }
                                    } else {
                                        // single
                                        string = values.category.title + ': <span style="font-weight:bold">' + string + '</span>';
                                    }
                                    return string;
                                }
                            }
                    ),
                    scope: me,
                    listeners: {
                        afterrender: function() {
                            me.addDataviewItemListeners();
                        }
                    }
                },
                {
                    xtype: 'combo',
                    fieldLabel: 'Add attribution',
                    queryMode: 'local',
                    displayField: 'value',
                    valueField: 'key',
                    store: Ext.create('Ext.data.Store', {
                        fields: ['key', 'value'],
                        data: [
                            {key: 'single', value: 'Single Attribute'},
                            {key: 'path', value: 'Path Interpolated'},
                            {key: 'filename', value: 'Filename Interpolated'}
                        ]
                    }),
                    listeners: {
                        change: function( combo, newVal, oldVal, opts ) {
                            var oldF = Ext.getCmp('addAttr'+oldVal);
                            var newF = Ext.getCmp('addAttr'+newVal);
                            if ( oldF ) oldF.hide();
                            if ( newF ) newF.show();
                        }
                    }
                },
                {
                    xtype: 'component',
                    html: '<div id="addAttrError" style="color: red; padding: 5px; font-weight: bold;"></div>'
                },
                {
                    xtype: 'panel',
                    border: false,
                    hidden: true,
                    id: 'addAttrsingle',
                    items: [
                        {
                            xtype: 'combo',
                            id: 'attributeSearchCombo',
                            emptyText: 'Type to search attributes.',
                            store: 'AttributesStore',
                            displayField: 'title',
                            queryParam: 'filter',
                            typeAhead: false,
                            minChars: 2,
                            hideLabel: true,
                            hideTrigger: true,
                            anchor: '100%',
                            width: 500,
                            listConfig: {
                                loadingText: 'Looking for attributes...',
                                emptyText: 'No matching attributes found.',
                                getInnerTpl: function() {
                                        return '<div class="attributeSearchItem">'+
                                                '<h3><span style="font-weight:bold">{categoryTitle}</span>: {title}</h3>'+
                                        '</div>';
                                }
                            },
                            pageSize: 10,
                            listeners: {
                                scope: this,
                                select: function(combo, selection) {
                                    var val = selection[0];
                                    if ( val ) {
                                        var tempAttribute = {
                                            id: me.mainForm.filter.tempId++,
                                            type: 'static',
                                            isAdd: true,
                                            isOverride: false,
                                            attributeId: val.get('attributeId'),
                                            category: {
                                                categoryId: val.get('categoryId'),
                                                bisId: val.get('bisId'),
                                                title: val.get('categoryTitle')
                                            },
                                            value: val.get('title'),
                                            fields: []
                                        };
                                        if ( me.attributeExists( tempAttribute ) ) {
                                            Ext.get('addAttrError').update('Attribute already exists.');
                                        } else {
                                            if ( tempAttribute.value != '' ) {
                                                me.mainForm.filter.attributes.push( tempAttribute );
                                                Ext.getCmp('filterAttributesPanel').update( me.mainForm.filter.attributes );
                                                me.addDataviewItemListeners();
                                                Ext.get('addAttrError').update('');
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    ]
                },
                {
                    xtype: 'panel',
                    border: false,
                    hidden: true,
                    id: 'addAttrpath',
                    items: [
                        {
                            xtype: 'component',
                            html: '<br>Interpolate attributes by mapping a file path. Note: This attribution will only apply to images matching the selected path. Also note that when attempting to match attributes within the specified categories, the software will automatically generate new attributes. For instance, if "Family" was specified within the path map, and a folder was named "Aceracae", but there is no attribute in "Family" named "Aceracae", then a new attribute will be created under "Family" with the title "Aceracae".<br>'
                        },
                        {
                            xtype: 'combo',
                            id: 'selectedpath',
                            width: 500,
                            fieldLabel: 'Select a path',
                            queryMode: 'local',
                            displayField: 'path',
                            valueField: 'path',
                            store: Ext.create('Ext.data.Store', {
                                fields: ['path'],
                                data: me.mainForm.filter.monitors
                            }),
                            listeners: {
                                change: function( combo, newVal, oldVal, opts ) {
                                    Ext.getCmp('pathnamecontainer').update( newVal );
                                    Ext.getCmp('pathboxlength').show();
                                }
                            }
                        },
                        {
                            xtype: 'combo',
                            id: 'pathboxlength',
                            hidden: true,
                            width: 500,
                            fieldLabel: 'Subfolders to map',
                            queryMode: 'local',
                            displayField: 'key',
                            valueField: 'value',
                            store: Ext.create('Ext.data.Store', {
                                fields: ['key','value'],
                                data: [
                                    { key: '1', value: 1 },
                                    { key: '2', value: 2 },
                                    { key: '3', value: 3 },
                                    { key: '4', value: 4 },
                                    { key: '5', value: 5 }
                                ]
                            }),
                            listeners: {
                                change: function( combo, newVal, oldVal, opts ) {
                                    var newComponents = [];
                                    for ( var i = 0; i < newVal; i++ ) {
                                        if ( i > 0 ) newComponents.push( Ext.create('Ext.form.Label', { text: '/' }) );
                                        newComponents.push( Ext.create('BISC.view.CustomPathAttribute', { id: 'pathattr' + i }) );
                                    }
                                    Ext.getCmp('pathbox').removeAll();
                                    Ext.getCmp('pathbox').add( newComponents );
                                }
                            }
                        },
                        {
                            xtype: 'component',
                            id: 'pathnamecontainer'
                        },
                        {
                            xtype: 'panel',
                            id: 'pathbox',
                            border: false,
                            layout: 'hbox'
                        },
                        {
                            xtype: 'component',
                            html: '/image.ext'
                        },
                        {
                            xtype: 'button',
                            scope: me,
                            handler: me.addCustomPath,
                            text: 'Add path attribution'
                        }
                    ]
                },
                {
                    xtype: 'panel',
                    border: false,
                    hidden: true,
                    id: 'addAttrfilename',
                    items: [
                        {
                            xtype: 'component',
                            html: '<br>Use regex.<br>'
                        },
                        {
                            xtype: 'textfield',
                            id: 'filenameRegex'
                        },
                        {
                            xtype: 'combo',
                            id: 'formatFilenameCombo',
                            queryMode: 'local',
                            displayField: 'value',
                            valueField: 'key',
                            store: Ext.create('Ext.data.Store', {
                                fields: ['key', 'value'],
                                data: [
                                    {key: 'upper', value: 'All Uppercase'},
                                    {key: 'lower', value: 'All Lowercase'},
                                    {key: 'ucfirst', value: 'First Character Uppercase'}
                                ]
                            }),
                            listeners: {
                                change: function( combo, newVal, oldVal, opts ) {
                                }
                            }
                        },
                        Ext.create('BISC.view.CustomPathAttribute', { id: 'filenameCat' }),
                        {
                            xtype: 'button',
                            scope: me,
                            handler: me.addCustomFilename,
                            text: 'Add filename attribution'
                        }
                    ]
                }
            ]
        });
        
        me.callParent(arguments);
    },
    addCustomPath: function() {
        var me = this;
        var tempAttribute = {
            id: me.mainForm.filter.tempId++,
            type: 'pathinterpolation',
            isAdd: true,
            isOverride: false,
            attributeId: '',
            category: {
                categoryId: '',
                title: '',
                bisId: ''
            },
            value: Ext.getCmp('selectedpath').getValue(),
            fields: []
        };
        var pathLength = Ext.getCmp('pathboxlength').getValue();
        var pathComponents = [];
        var flag = true;
        if ( pathLength != '' && pathLength != null ) {
            for ( var i = 0; i < pathLength; i++ ) {
                var val = Ext.getCmp('pathattr' + i).getValue();
                var categoryRecord = Ext.getCmp('pathattr' + i).findRecordByValue( val );
                if ( val == '' || val == null ) {
                    flag = false;
                    Ext.get('addAttrError').update('Please choose a category for each path segment.');
                } else {
                    tempAttribute.fields.push({
                        text: '{' + val + '}',
                        title: val,
                        id: categoryRecord.get('categoryId'),
                        bisId: categoryRecord.get('bisId')
                    });
                }
            }
            if ( flag ) {
                me.mainForm.filter.attributes.push( tempAttribute );
                Ext.getCmp('filterAttributesPanel').update( me.mainForm.filter.attributes );
                me.addDataviewItemListeners();
                Ext.get('addAttrError').update('');
            }
        }
    },
    addCustomFilename: function() {
        var me = this;
        var flag = true;
        var tempAttribute = {
            id: me.mainForm.filter.tempId++,
            type: 'filenameinterpolation',
            isAdd: true,
            isOverride: false,
            attributeId: '',
            category: {
                categoryId: '',
                title: '',
                bisId: ''
            },
            value: Ext.getCmp('filenameRegex').getValue(),
            format: Ext.getCmp('formatFilenameCombo').getValue(),
            fields: []
        };
        var val = Ext.getCmp('filenameCat').getValue();
        var categoryRecord = Ext.getCmp('filenameCat').findRecordByValue( val );
        if ( val == '' || val == null ) {
            flag = false;
            Ext.get('addAttrError').update('Please choose a category for the matched filename.');
        } else {
            tempAttribute.fields.push({
                text: '{' + val + '}',
                title: val,
                id: categoryRecord.get('categoryId'),
                bisId: categoryRecord.get('bisId')
            });
        }
        if ( flag ) {
            me.mainForm.filter.attributes.push( tempAttribute );
            Ext.getCmp('filterAttributesPanel').update( me.mainForm.filter.attributes );
            me.addDataviewItemListeners();
            Ext.get('addAttrError').update('');
        }
    },
    addDataviewItemListeners: function() {
        Ext.getCmp('filterAttributesPanel').getEl().select('.removeAttributeBtn').each( function( el ) {
            el.on( 'click', function( e, el, opts ) {
                var attributeId = el.getAttribute( 'attribute-id' );
                var attributes = Ext.getCmp('createFilterPanel').filter.attributes;
                Ext.each( attributes, function( attribute ) {
                    if ( attribute.id == attributeId ) {
                        attributes.splice( attributes.indexOf( attribute ), 1 );
                        Ext.getCmp('filterAttributesPanel').update( attributes );
                        Ext.getCmp('formAddFilterAttribute').addDataviewItemListeners();
                        return;
                    }
                });
            });
        });
        Ext.getCmp('filterAttributesPanel').getEl().select('.toggleAdditiveBtn').each( function( el ) {
            el.on( 'click', function( e, el, opts ) {
                var attributeId = el.getAttribute( 'attribute-id' );
                var attributes = Ext.getCmp('createFilterPanel').filter.attributes;
                Ext.each( attributes, function( attribute ) {
                    if ( attribute.id == attributeId ) {
                        attribute.isAdd = !attribute.isAdd;
                        Ext.getCmp('filterAttributesPanel').update( attributes );
                        Ext.getCmp('formAddFilterAttribute').addDataviewItemListeners();
                        return;
                    }
                });
            });
        });
        Ext.getCmp('filterAttributesPanel').getEl().select('.overrideCbx').each( function( el ) {
            el.on( 'click', function( e, el, opts ) {
                var attributeId = el.getAttribute( 'attribute-id' );
                var attributes = Ext.getCmp('createFilterPanel').filter.attributes;
                Ext.each( attributes, function( attribute ) {
                    if ( attribute.id == attributeId ) {
                        attribute.isOverride = !attribute.isOverride;
                        return;
                    }
                });
            });
        });
    },
    attributeExists: function( newAttribute ) {
        var flag = false;
        Ext.each( this.mainForm.filter.attributes, function( attribute ) {
            if ( attribute.attributeId == newAttribute.attributeId ) flag = true;
        });
        return flag;
    }
});

Ext.define('BISC.view.FilterManagerMonitorsInput', {
    extend: 'Ext.form.Panel',
    alias: ['widget.filtermanagermonitorsinput'],
    id: 'formAddFilterMonitor',
    title: 'Monitors',
    border: false,
    bodyPadding: 10,
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'panel',
                    border: false,
                    id: 'filterMonitorsPanel',
                    data: me.mainForm.filter.monitors,
                    tpl: new Ext.XTemplate('<tpl for=".">' +
                                    '<div>' +
                                        '<button class="removeMonitorBtn" monitor-id="{id}">Remove</button>' +
                                        '<input class="monitorExactCbx" checked="{[this.isChecked(values.isExact)]}"monitor-id="{id}" type="checkbox"> ' +
                                        '{path}' +
                                    '</div>' +
                                '</tpl>', {
                                    isChecked: function( isExact ) {
                                        if ( isExact ) return 'checked';
                                        return '';
                                    }
                                }
                    )
                },
                {
                    xtype: 'component',
                    html: '<div id="addMonError" style="color: red; padding: 5px; font-weight: bold;"></div>'
                },
                {
                    xtype: 'panel',
                    border: false,
                    layout: 'hbox',
                    items: [
                        {
                            xtype: 'radio',
                            id: 'monitorByIdRadio',
                            name: 'monitorGroup',
                            value: 'monitorById',
                            checked: true
                        },
                        {
                            xtype: 'combo',
                            id: 'addMonitorId',
                            fieldLabel: 'Add monitor',
                            displayField: 'path',
                            width: 500,
                            valueField: 'path',
                            store: 'FolderListStore',
                            listeners: {
                                focus: function() {
                                    Ext.getCmp('monitorByIdRadio').setValue( true );
                                }
                            }
                        }
                    ]
                },
                {
                    xtype: 'panel',
                    border: false,
                    layout: 'hbox',
                    items: [
                        {
                            xtype: 'radio',
                            id: 'monitorByInputRadio',
                            name: 'monitorGroup',
                            value: 'monitorByInput'
                        },
                        {
                            xtype: 'textfield',
                            id: 'addMonitorPath',
                            width: 500,
                            fieldLabel: 'or custom path',
                            enableKeyEvents: true,
                            scope: me,
                            listeners: {
                                scope: me,
                                keypress: function( field, e, opts ) {
                                    if ( e.keyCode == e.ENTER ) {
                                        var value = field.getValue();
                                        if ( value != '' ) {
                                            this.addMonitor();
                                        }
                                    }
                                },
                                focus: function() {
                                    Ext.getCmp('monitorByInputRadio').setValue( true );
                                }
                            }
                        }
                    ]
                },
                {
                    xtype: 'button',
                    text: 'Add Monitor',
                    scope: me,
                    handler: me.addMonitor
                }
            ]
        });

        me.callParent(arguments);
    },
    addMonitor: function() {
        var me = this;
        if ( Ext.getCmp('monitorByIdRadio').checked ) {
            var tempMonitor = {
                id: me.mainForm.filter.tempId++,
                isExact: true,
                isMonitor: false,
                path: Ext.getCmp('addMonitorId').getValue()
            };
            if ( me.monitorExists( tempMonitor ) ) {
                Ext.get('addMonError').update('Monitor already exists.');
            } else {
                if ( tempMonitor.path != '' && tempMonitor.path != null ) {
                    me.mainForm.filter.monitors.push( tempMonitor );
                    Ext.getCmp('filterMonitorsPanel').update( me.mainForm.filter.monitors);
                    Ext.getCmp('selectedpath').getStore().load();
                    me.addDataviewItemListeners();
                    Ext.get('addMonError').update('');
                }
            }
        } else {
            var tempMonitor = {
                id: me.mainForm.filter.tempId++,
                isExact: true,
                isMonitor: false,
                path: Ext.getCmp('addMonitorPath').getValue()
            };
            if ( me.monitorExists( tempMonitor ) ) {
                Ext.get('addMonError').update('Monitor already exists.');
            } else {
                if ( tempMonitor.path != '' ) {
                    me.mainForm.filter.monitors.push( tempMonitor );
                    Ext.getCmp('filterMonitorsPanel').update( me.mainForm.filter.monitors );
                    Ext.getCmp('selectedpath').getStore().load();
                    me.addDataviewItemListeners();
                    Ext.get('addMonError').update('');
                }
            }
        }
    },
    addDataviewItemListeners: function() {
        Ext.getCmp('filterMonitorsPanel').getEl().select('.removeMonitorBtn').each( function( el ) {
            el.on( 'click', function( e, el, opts ) {
                var monitorId = this.getAttribute( 'monitor-id' );
                var monitors = Ext.getCmp('createFilterPanel').filter.monitors;
                Ext.each( monitors, function( monitor ) {
                    if ( monitor.id == monitorId ) {
                        monitors.splice( monitors.indexOf( monitor ), 1 );
                        Ext.getCmp('filterMonitorsPanel').update( monitors );
                        Ext.getCmp('formAddFilterMonitor').addDataviewItemListeners();
                        return;
                    }
                });
            });
        });
        Ext.getCmp('filterMonitorsPanel').getEl().select('.monitorExactCbx').each( function( el ) {
            el.on( 'click', function( e, el, opts ) {
                var monitorId = this.getAttribute( 'monitor-id' );
                var monitors = Ext.getCmp('createFilterPanel').filter.monitors;
                Ext.each( monitors, function( monitor ) {
                    if ( monitor.id == monitorId ) {
                        monitor.isExact = !monitor.isExact;
                        return;
                    }
                });
            });
        });
    },
    monitorExists: function( newMonitor ) {
        var flag = false;
        Ext.each( this.mainForm.filter.monitors, function( monitor ) {
            if ( monitor.path == newMonitor.path ) flag = true;
        });
        return flag;
    }
});

Ext.define('BISC.view.FormCreateFilter', {
    extend: 'Ext.panel.Panel',
    alias: ['widget.formcreatefilter'],
    requires: [
        'BISC.view.FilterManagerRulesInput',
        'BISC.view.FilterManagerMonitorsInput',
        'BISC.view.FilterManagerAttributesInput'
    ],
    id: 'createFilterPanel',
    border: false,

    initComponent: function() {
        var me = this;

        var form = Ext.create('Ext.form.Panel',{
            id: 'formCreateFilter',
            bodyPadding: 10,
            border: false,
            items: [
                {
                    xtype: 'textfield',
                    id: 'filterNameField',
                    fieldLabel: 'Filter Name',
                    labelAlign: 'right',
                    anchor: '100%',
                    name: 'name'
                }
            ]
        });

        if ( this.filter.data ) {
            Ext.getCmp('formCreateFilter').loadRecord( this.filter );
            var parsedFilter = this.filter.get('data');
            try {
                parsedFilter = JSON.parse( parsedFilter );
            } catch ( err ) {
                // already parsed
            }
            parsedFilter.filterId = this.filter.get('filterId');
            this.filter = parsedFilter;
        }

        var monitorsForm = Ext.create( 'BISC.view.FilterManagerMonitorsInput', { mainForm: me } );
        var rulesForm = Ext.create( 'BISC.view.FilterManagerRulesInput', { mainForm: me } );
        var attributesForm = Ext.create( 'BISC.view.FilterManagerAttributesInput', { mainForm: me } );

        console.log( this.filter );
        Ext.applyIf(me, {
            items: [
                form,
                {
                    xtype: 'tabpanel',
                    activeTab: 0,
                    border: false,
                    items: [
                        monitorsForm,
                        rulesForm,
                        attributesForm
                    ]
                }
            ],
            dockedItems: [
                {
                    xtype: 'toolbar',
                    ui: 'footer',
                    dock: 'bottom',
                    items: [
                        '->',
                        {
                            xtype: 'button',
                            text: 'Cancel',
                            scope: this,
                            handler: this.cancel
                        },
                        {
                            xtype: 'button',
                            text: 'Simulate Filter',
                            scope: me,
                            handler: this.test
                        },
                        {
                            xtype: 'button',
                            text: ( this.filter.filterId ) ? 'Update Filter' : 'Add Filter',
                            scope: me,
                            handler: this.submit
                        }
                    ]
                } 
            ]
        });

        me.callParent(arguments);
    },
    test: function() {
        var me = this;
        var values = {
            name: Ext.getCmp('filterNameField').getValue(),
            enabled: 0
        };
        me.filter.name = values.name;
        values.data = JSON.stringify( me.filter );

        Ext.Ajax.request({
            method: 'POST',
            url: 'http://localhost:8888/testFilter',
            jsonData: values,
            scope: this,
            success: function( resObj ) {
                var res = Ext.decode( resObj.responseText );
                if ( res.success ) {
                    // clear any errors
                    if ( Ext.get('addCmpError') ) Ext.get('addCmpError').update( '' );
                    if ( Ext.get('addMonError') ) Ext.get('addMonError').update( '' );
                    if ( Ext.get('addAttrError') ) Ext.get('addAttrError').update( '' );
                    var me = this;
                    var tmpWindow = Ext.create('Ext.window.Window', {
                        title: 'Filter Simulation Results (' + res.data.length + ' matches.)',
                        iconCls: 'icon_simulation',
                        modal: true,
                        height: 500,
                        width: 800,
                        layout: 'fit',
                        scope: this,
                        items: [
                            {
                                xtype: 'panel',
                                autoScroll: true,
                                data: res.data,
                                tpl: new Ext.XTemplate( '<tpl for=".">' +
                                        '<div>{image.filepath}/{image.path}</div>' +
                                        '<div><tpl for="attributes">' +
                                            '<div style="margin-left: 20px;">{testInfo.prefix} <span style="color:{testInfo.color}; font-weight: bold;">{[this.printMainText(values)]}</span></div>' +
                                        '</tpl></div>' +
                                    '</tpl>', {
                                        printMainText: function( values ) {
                                            var string = ( typeof values.value == 'undefined' ) ? values.categoryTitle : values.value;
                                            if ( values.fields && values.fields.length > 0 ) {
                                                if ( values.value.charAt( values.value.length-1 ) != '/' ) string += '/';
                                                Ext.each( values.fields, function( field ) {
                                                    string += '<span style="font-weight:bold">' + field.text + '</span>/';
                                                });
                                                string += 'image.ext';
                                            }
                                            if ( !values.category && !values.fields ) {
                                                string = values.name;
                                            }
                                            return string;
                                        }
                                    }
                                )
                            }
                        ],
                        dockedItems: [
                            {
                                xtype: 'toolbar',
                                ui: 'footer',
                                dock: 'bottom',
                                scope: me,
                                items: [
                                    {
                                        xtype: 'button',
                                        text: 'Run Once',
                                        scope: me,
                                        handler: function() {
                                            var me = this;
                                            var values = {
                                                name: Ext.getCmp('filterNameField').getValue(),
                                                enabled: 0
                                            };
                                            me.filter.name = values.name;
                                            values.data = JSON.stringify( me.filter );
                                            Ext.getCmp('statusLabel').update('Initializing filter...');

                                            Ext.Ajax.request({
                                                method: 'POST',
                                                url: 'http://localhost:8888/runFilter',
                                                jsonData: values,
                                                scope: me,
                                                success: function( resObj ) {
                                                    var res = Ext.decode( resObj.responseText );
                                                    if ( res.success ) {
                                                        Ext.getCmp('statusLabel').update('Checking attributes...');
                                                    }
                                                }
                                            });
                                            this.cancel();
                                        }
                                    },
                                    '->',
                                    {
                                        xtype: 'button',
                                        text: 'Close',
                                        handler: function() { this.ownerCt.ownerCt.fireEvent('done') }
                                    }
                                ]
                            }
                        ]
                    }).show();
                    tmpWindow.on( 'done', function( data ) {
                        tmpWindow.close();
                    });
                } else {
                    if ( Ext.get('addCmpError') ) Ext.get('addCmpError').update( res.error.message );
                    if ( Ext.get('addMonError') ) Ext.get('addMonError').update( res.error.message );
                    if ( Ext.get('addAttrError') ) Ext.get('addAttrError').update( res.error.message );
                }
            }
        });
    },
    submit: function() {
        var me = this;
        var values = {
            name: Ext.getCmp('filterNameField').getValue(),
            enabled: 0
        };
        if ( this.filter.filterId ) values.filterId = this.filter.filterId;
        me.filter.name = values.name;
        values.data = JSON.stringify( me.filter );
        var route = ( this.filter.filterId ) ? 'updateFilter' : 'addFilter';
        Ext.Ajax.request({
            method: 'POST',
            url: 'http://localhost:8888/' + route,
            jsonData: values,
            scope: this,
            success: function( resObj ) {
                var res = Ext.decode( resObj.responseText );
                if ( res.success ) {
                    this.ownerCt.fireEvent('done');
                } else {
                    if ( Ext.get('addCmpError') ) Ext.get('addCmpError').update( res.error.message );
                    if ( Ext.get('addMonError') ) Ext.get('addMonError').update( res.error.message );
                    if ( Ext.get('addAttrError') ) Ext.get('addAttrError').update( res.error.message );
                }
            }
        });
    },
    cancel: function() {
        this.ownerCt.fireEvent( 'done' );
    }
});

Ext.define('BISC.view.FilterManagerPanel', {
	extend: 'Ext.panel.Panel',
	alias: ['widget.filtermanagerpanel'],
	requires: [
        'BISC.view.FormCreateFilter',
        'BISC.view.CtxMnuFilter'
    ],
	id: 'filterManagerPanel',
	layout: 'fit',
	border: false,
	bodyBorder: false,
	initComponent: function() {
		var me = this;
		Ext.applyIf(me, {
			items: [{
				xtype: 'tabpanel',
				id: 'filterManagerTabPanel',
				activeTab: 0,
                border: false,
                layout: 'fit',
				items: [{
					xtype: 'gridpanel',
					iconCls: 'icon_filters',
					title: 'Automatic Attribution',
					id: 'filtersGrid',
					border: false,
					store: 'FiltersStore',
					columns: [
                        {
						    dataIndex: 'name',
						    text: 'Name',
                            flex: 2
					    },
                        {
                            xtype: 'booleancolumn',
                            dataIndex: 'enabled',
                            text: 'Enabled?',
                            flex: 1,
                            falseText: 'No',
                            trueText: 'Yes',
                            undefinedText: 'n/a'
					    },
                        {
                            dataIndex: 'data',
                            text: 'Filter Object',
                            flex: 6
                        }
                    ],
                    scope: this,
					listeners: {
						itemdblclick: function( grid, record, el, ind, e, opts ) {
                            var me = this;
                            var form = Ext.create( 'BISC.view.FormCreateFilter', { filter: record } );
							var wndw = Ext.create('Ext.window.Window', {
								title: 'Edit Filter',
								iconCls: 'icon_editFilter',
								modal: true,
								height: 500,
								width: 800,
								layout: 'fit',
								items: [
                                    form
                                ]
							}).show();
                            wndw.on( 'done', function() {
                                wndw.close();
                                Ext.getCmp('filtersGrid').getStore().load();
                            });
						},
						itemcontextmenu: function(view, record, item, index, e) {
							e.stopEvent();
							Ext.create('BISC.view.CtxMnuFilter', {record: record}).showAt( e.getXY() );
						}
					},
					dockedItems: [{
						xtype: 'toolbar',
						dock: 'top',
						items: [{
							text: 'Add Filter',
							iconCls: 'icon_addFilter',
							scope: this,
							handler: this.createFilter
						}]
					}]
				}]
			}]
		});

		me.callParent(arguments);
	},
	createFilter: function() {
        var me = this;
        var form = Ext.create( 'BISC.view.FormCreateFilter', {
            filter: {
                name: '',
                enabled: false,
                tempId: 0,
                monitors: [],
                filters: [],
                attributes: []
            }
        });
		var tmpwndw = Ext.create('Ext.window.Window', {
			title: 'Add New Filter',
			iconCls: 'icon_addFilter',
			modal: true,
			height: 500,
			width: 800,
			layout: 'fit',
			items: [
                form
			]
		}).show();
        tmpwndw.on( 'done', function() {
            tmpwndw.close();
            Ext.getCmp('filtersGrid').getStore().load();
        });
	}
});

Ext.define('BISC.view.FilterManagerWindow', {
    extend: 'Ext.window.Window',
    height: 600,
    id: 'filterManagerWindow',
    width: 800,
    title: 'Attribution Manager',
    bodyBorder: false,
    initComponent: function() {
        var me = this;

        var manager = Ext.create( 'BISC.view.FilterManagerPanel' );

        manager.on( 'done', function() {
            me.close();
        });

        Ext.applyIf(me, {
            items: [
                manager
            ],
            dockedItems: [
                {
                    xtype: 'toolbar',
                    ui: 'footer',
                    dock: 'bottom',
                    items: [
                        '->',
                        {
                            xtype: 'button',
                            width: 75,
                            text: 'Close',
                            scope: me,
                            handler: me.onClose
                        }
                    ]
                }
            ]
        });

        me.callParent(arguments);
    },

    onClose: function(button, e, options) {
        // fire close event on parent
        this.hide();
    }

});

Ext.define('BISC.view.FormCreateAttribute', {
    extend: 'Ext.form.FormPanel',
    alias: ['widget.formcreateattribute'],
    id: 'formCreateAttribute',
    bodyPadding: 10,
    initComponent: function() {
        var me = this;
        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'textfield',
                    name: 'name',
                    fieldLabel: 'Name',
                    labelAlign: 'right',
                    allowBlank: false,
                    anchor: '100%'
                },
                {
                    xtype: 'textfield',
                    name: 'attributeId',
                    fieldLabel: 'Identifier',
                    labelAlign: 'right',
                    anchor: '100%',
                    readOnly: true,
                    fieldCls: 'x-item-disabled',
                    hidden: this.mode == 'add'
                },
                {
                    xtype: 'textfield',
                    name: 'categoryId',
                    value: this.record.data.categoryId,
                    fieldLabel: 'Category',
                    labelAlign: 'right',
                    anchor: '100%',
                    readOnly: true,
                    fieldCls: 'x-item-disabled'
                },
                {
                    xtype: 'hiddenfield',
                    name: 'bisId',
                    value: Config.server.id
                }
            ],
            dockedItems: [
                {
                    xtype: 'toolbar',
                    dock: 'bottom',
                    ui: 'footer',
                    items: [
                        {
                            text: ( this.mode == 'add' ) ? 'Add' : 'Update',
                            scope: this,
                            handler: this.submitForm
                        },
                        '->',
                        {
                            text: 'Cancel',
                            scope: this,
                            handler: this.cancel
                        },
                    ]
                }
            ]
        });

        me.callParent(arguments);
    },
    listeners: {
        afterrender: function() {
            if ( this.mode != 'add' ) {
                // edit
                Ext.getCmp('formCreateAttribute').loadRecord( this.record );
            }
        }
    },

	submitForm: function() {
        var me = this;
		var form = Ext.getCmp('formCreateAttribute').getForm();
		form.url = 'http://localhost:8888/attributes/create';
		if ( form.isValid() ) {
			form.submit({
				success: function(form, action) {
                     me.ownerCt.fireEvent('attributeCreated', action);
				},
				failure: function(form, action) {
                    var res = Ext.decode( action.response.responseText );
                    Ext.Msg.alert('Attribute could not be created.', res.error.message);
				}
			});
		}
    },
    cancel: function() {
        this.ownerCt.fireEvent('cancel');
    }
});

Ext.define('BISC.view.MonitorsPanel', {
    extend: 'Ext.panel.Panel',

    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'dataview',
                    id: 'monitorListDataview',
                    border: false,
                    style: 'background-color: white',
                    itemSelector: 'div.monitorSel',
                    selectedItemCls: 'monitorSelect',
                    overItemCls: 'monitorHover',
                    trackOver: true,
                    store: 'FolderListStore',
                    itemTpl: new Ext.XTemplate(
                        '<div class="monitorSel" style="position: relative; margin-bottom: 5px;">' +
                            '<div><span style="color: gray; font-size: 10px;">{subpath}</span></div>' +
                            '<div>{text}</div>' +
                            '<div style="position: absolute; right: 0px; top: 0px; padding: 5px; magin: 5px;"><span style="font-weight: bold">{sz}</span> images</div>' +
                        '</div>'
                    ),
                    scope: this,
                    listeners: {
                        itemcontextmenu: function(view, record, item, index, e) {
                            e.stopEvent();
                            var ctx = Ext.create('BISC.view.CtxMnuMonitorList', {record: record});
                            ctx.showAt(e.getXY());
                        },
                        itemdblclick: function( grid, record, el, ind, e, opts ) {
                            Ext.StoreManager.lookup('ImagesStore').getProxy().extraParams.folderId = record.data.id;
                            Ext.StoreManager.lookup('ImagesStore').getProxy().extraParams.bisId = Config.server.id;
                            Ext.StoreManager.lookup('ImagesStore').load();
                        }
                    }
                }
            ],
            dockedItems: [
                {
                    xtype: 'toolbar',
                    dock: 'top',
                    border: false,
                    items: [
                        {
                            xtype: 'tbfill'
                        },
                        {
                            xtype: 'textfield',
                            fieldLabel: 'Search',
                            labelWidth: 40
                        }
                    ]
                }
            ]
        });

        me.callParent(arguments);
    }

});

Ext.define('BISC.view.CtxMnuAttribute', {
    extend: 'Ext.menu.Menu',
    scope: this,
    listeners: {
        click: function( menu, item ) {
            switch( item.identifier ) {
                case 'update':
                    this.update();
                    break;
                case 'delete':
                    Ext.Msg.confirm('Remove ' + this.record.data.title + '?', 'Are you sure you want remove ' + this.record.data.title + '?', function( btn, nothing, item ) {
                        if ( btn == 'yes' ) this.remove();
                    }, this);
                    break;
            }
        }
    },
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    text: 'Edit',
                    iconCls: 'icon_editAttribute',
                    identifier: 'update'
                },
                {
                    text: 'Remove',
                    iconCls: 'icon_removeAttribute',
                    identifier: 'delete'
                }
            ]
        });
        me.callParent(arguments);
    },
    remove: function() {
        Ext.data.JsonP.request({
            url: Config.serverUrl + 'resources/api/api.php',
            params: {
                cmd: 'attributeDelete',
                attributeId: this.record.data.attributeId
            },
            scope: this,
            callback: function( success, res ) {
                if ( res.success ) {
                    
                }
            }
        });
    },
    update: function() {
        var tmpWindow = Ext.create('Ext.window.Window', {
            title: 'Edit Attribute ' + this.record.data.title,
            iconCls: 'icon_editAttribute',
            modal: true,
            height: 100,
            width: 350,
            layout: 'fit',
            items: [
                Ext.create('widget.formcreateattribute', {
                    record: this.record,
                    mode: 'edit'
                })
            ]
        }).show();
        tmpWindow.on( 'attributeCreated', function( data ) {
            tmpWindow.close();
            // kue finish job will emit update event on treegrid
        });
    }
});

Ext.define('BISC.view.CtxMnuCategory', {
    extend: 'Ext.menu.Menu',
    scope: this,
    listeners: {
        click: function( menu, item ) {
            switch( item.identifier ) {
                case 'create':
                    var me = this;
                    var tmpWindow = Ext.create('Ext.window.Window', {
                        title: 'Add Attribute to ' + this.record.data.title,
                        iconCls: 'icon_newAttribute',
                        modal: true,
                        height: 100,
                        width: 350,
                        layout: 'fit',
                        items: [
                            Ext.create('widget.formcreateattribute', {
                                record: this.record,
                                mode: 'add'
                            })
                        ]
                    }).show();
                    tmpWindow.on('attributeCreated', function( data ) {
                        tmpWindow.close();
                        // don't reload store here... kue finish event caught by server which emits update
                    });
                    tmpWindow.on( 'cancel', function( data ) {
                        tmpWindow.close();
                    });
                    break;
                case 'update':
                    var me = this;
                    var tmpWindow = Ext.create('Ext.window.Window', {
                        title: 'Edit ' + this.record.data.title,
                        iconCls: 'icon_editCategory',
                        modal: true,
                        height: 150,
                        width: 350,
                        layout: 'fit',
                        items: [
                            Ext.create('widget.formcreatecategory', {
                                record: this.record,
                                mode: 'edit'
                            })
                        ]
                    }).show();
                    tmpWindow.on('categoryCreated', function( data ) {
                        tmpWindow.close();
                        Ext.getCmp('categoryTreePanel').getStore().load();
                    });
                    tmpWindow.on( 'cancel', function( data ) {
                        tmpWindow.close();
                    });
                    break;
                case 'delete':
                    Ext.Msg.confirm('Remove Category', 'Are you sure you want remove "' + this.record.data.title + '"?', function( btn, nothing, item ) {
                        if ( btn == 'yes' ) this.remove();
                    }, this);
                    break;
            }
        }
    },
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    text: 'Add Attribute',
                    iconCls: 'icon_newAttribute',
                    identifier: 'create'
                },
                '-',
                {
                    text: 'Edit Category',
                    iconCls: 'icon_editCategory',
                    identifier: 'update'
                },
                {
                    text: 'Remove Category',
                    iconCls: 'icon_removeCategory',
                    identifier: 'delete'
                }
            ]
        });
        me.callParent(arguments);
    },
    remove: function() {
        Ext.data.JsonP.request({
            url: 'http://8888/categories/delete',
            params: {
                categoryId: this.record.data.categoryId
            },
            scope: this,
            callback: function( success, res ) {
                if ( res.success ) {
                    Ext.getCmp('categoryTreePanel').getStore().load();
                }
            }
        });
    }
});

Ext.define('BISC.view.FormCreateCategory', {
	extend: 'Ext.form.FormPanel',
	alias: ['widget.formcreatecategory'],
	id: 'formCreateCategory',
	bodyPadding: 10,
	initComponent: function() {
        var me = this;
        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'textfield',
                    name: 'title',
                    focus: true,
                    fieldLabel: 'Name',
                    labelAlign: 'right',
                    allowBlank: false,
                    anchor: '100%'
                },
                {
                    xtype: 'textfield',
                    name: 'categoryId',
                    fieldLabel: 'Identifier',
                    labelAlign: 'right',
                    anchor: '100%',
                    readOnly: true,
                    fieldCls: 'x-item-disabled',
                    hidden: this.mode == 'add'
                },
                {
                    xtype: 'hiddenfield',
                    name: 'bisId',
                    value: Config.server.id
                }
            ],
            dockedItems: [{
                xtype: 'toolbar',
                dock: 'bottom',
                ui: 'footer',
                items: [
                    {
                        text: ( this.mode == 'add' ) ? 'Add' : 'Update',
                        scope: this,
                        handler: this.submitForm
                    },
                    '->',
                    {
                        text: 'Cancel',
                        scope: this,
                        handler: this.cancel
                    }
                ]
            }]
        });
        me.callParent(arguments);
	},
    scope: this,
	listeners: {
		afterrender: function() {
			if ( this.mode != 'add' ) {
				// edit
                Ext.getCmp('formCreateCategory').loadRecord( this.record );
			}
		}
	},
	
	submitForm: function() {
        var me = this;
		var form = Ext.getCmp('formCreateCategory').getForm();
        form.url = 'http://localhost:8888/categories/create';
		if ( form.isValid() ) {
			form.submit({
                scope: this,
				success: function(form, action, a) {
                    me.ownerCt.fireEvent( 'categoryCreated', Ext.decode(action.response.responseText) );
				},
				failure: function(form, action) {
                    Ext.Msg.alert('Failed', 'Request Failed');
				}
			});
		}
	},
    cancel: function() {
        this.ownerCt.fireEvent('cancel');
    }
});

Ext.define('BISC.view.PropertiesPanel', {
    extend: 'Ext.panel.Panel',

    style: 'background-color: white',
    initComponent: function() {
        var me = this;
        var image = { id: null };

        Ext.applyIf(me, {
            items: [
                {
                    xtype: 'dataview',
                    cls: 'properties',
                    id: 'propertiesView',
                    tpl: [
                        '<tpl for=".">',
                            '<div class="property">',
                                '{title}: <span style="font-weight: bold;">{name}</span>',
                            '</div>',
                        '</tpl>'
                    ],
                    emptyText: 'This image has to metadata.',
                    itemSelector: 'div.property'
                }
            ]
        });

        me.callParent(arguments);
    }

});

Ext.define('BISC.view.ServerManagerWindow', {
    extend: 'Ext.window.Window',
    height: 600,
    id: 'serverManagerWindow',
    width: 800,
    title: 'Server Manager',
    bodyBorder: false,
    initComponent: function() {
        var me = this;

        var manager = Ext.create( 'BISC.view.ServerManagerPanel' );

        manager.on( 'done', function() {
            me.close();
        });

        Ext.applyIf(me, {
            items: [
                manager
            ],
            dockedItems: [
                {
                    xtype: 'toolbar',
                    ui: 'footer',
                    dock: 'bottom',
                    items: [
                        '->',
                        {
                            xtype: 'button',
                            width: 75,
                            text: 'Close',
                            scope: me,
                            handler: me.onClose
                        }
                    ]
                }
            ]
        });

        me.callParent(arguments);
    },

    onClose: function(button, e, options) {
        // fire close event on parent
        this.hide();
    }

});

Ext.define('BISC.view.ImagesPanel', {
    extend: 'Ext.panel.Panel',

    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            tplBoth: new Ext.XTemplate(
            '<tpl for=".">' +
                '<div class="imageSel" style="position: relative; margin: auto; height: 150px; clear: both;">' +
                    '<img src="data:image/jpeg;base64,{thumbnail}" onerror="this.src=\'http://placehold.it/150x150&text=Generating Thumbnail\'" style="max-width: 150px; max-height: 150px; float: left;" alt="{path}">' +
                    '<div style="float: left;">' +
                        // image path
                        '<div style="margin: 10px;"><span style="font-weight: bold;">{path}</span></div>' +
                        // status icons
                        '<div style="padding: 5px; margin: 10px; top: 0px; right: 0px; position: absolute;">' +
                            // sync'd
                            '<tpl if="thumbnail != null"><img src="/resources/img/ico/synchronized.png" data-qtip="{timestampModified}" style="padding: 5px;"></tpl>' +
                            // not sync'd
                            '<tpl if="thumbnail == null"><img src="/resources/img/ico/unsynchronized.png" data-qtip="This image may be in the process queue." style="padding: 5px;"></tpl>' +
                            // blacklisted
                            '<tpl if="blackList == 1">' +
                                // error blacklisted
                                '<tpl if="error != \'\'">' +
                                    '<img src="/resources/img/ico/blacklisted.png" data-qtip="Cannot upload image to server. Does file extension match file type?" style="padding: 5px;">' +
                                    '<img src="/resources/img/ico/error.png" data-qtip="{error}" style="padding: 5px;">' +
                                '</tpl>' +
                                // user blacklisted
                                '<tpl if="error == \'\'"><img src="/resources/img/ico/blacklisted.png" data-qtip="Blacklisted images are not uploaded to the server." style="padding: 5px;"></tpl>' +
                            '</tpl>' +
                            // uploaded
                            '<tpl if="online == 1"><img src="/resources/img/ico/uploaded.png" data-qtip="{lastUploaded}" style="padding: 5px;"></tpl>' +
                        '</div>' +
                    '</div>' +
                '</div>' +
            '</tpl>'),
            tplSmall: new Ext.XTemplate(
                '<tpl for=".">'+
                '<div class="imageSel" style="width: 100px; height: 100px; display: inline-block;">' +
                    '<div>'+
                        '<img src="data:image/jpeg;base64,{thumbnail}" onerror="this.src=\'http://placehold.it/100x100&text=Generating Thumbnail\'" style="display: block; margin: auto; max-width: 100px; max-height: 100px;"" alt="{path}">' +
                    '</div>'+
                '</div>'+
                '</tpl>'
            ),
            tplLarge: new Ext.XTemplate(
                '<tpl for=".">'+
                '<div class="imageSel" style="display: inline-block;">' +
                    '<div style="padding: 5px;">'+
                        '<div>'+
                            '<span style="font-weight:bold">{path}</span><br/>{barcode} {family}<br/>{genus} {specificEpithet}'+
                        '</div>'+
                        '<div style="border-bottom: solid thin #9F9F9F; width: 275px; height: 276px;">'+
                            '<img src="data:image/jpeg;base64,{thumbnail}" onerror="this.src=\'http://placehold.it/275x276&text=Generating Thumbnail\'" style="display: block; margin: auto; max-width: 275px; max-height: 275px;" alt="{path}">' +
                        '</div>'+
                    '</div>'+
                '</div>'+
                '</tpl>'
            ),
            items: [
                {
                    xtype: 'dataview',
                    id: 'ImagesView',
                    overItemCls: 'imageHover',
                    selectedItemCls: 'imageSelect',
                    trackOver: true,
                    tpl: me.tplBoth,
                    autoScroll: true,
                    emptyText: '<div class=\'emptyText\'>No images available.</div>',
                    itemSelector: 'div.imageSel',
                    store: 'ImagesStore',
                    scope: me,
                    listeners: {
                        itemcontextmenu: me.onImagesViewItemContextMenu,
                        itemclick: function( dataview, record, el, ind, e ) {
                            var bar = Ext.getCmp('imageDetailsBar');
                            bar.update( record.get('path') + ' - ' + record.get('timestampModified') );
                            bar.show();
                            Ext.data.JsonP.request({
                                url: 'http://localhost:8888/imageListAttributes',
                                params: {
                                    imageId: record.get('id'),
                                    bisId: Config.server.id
                                },
                                callback: function( success, data ) {
                                    Ext.getCmp('propertiesView').image = record.data;
                                    Ext.getCmp('propertiesView').update( data.records );
                                }
                            });
                        },
                        itemmouseenter: function( dataview, record, el, ind, e ) {
                            var store = Ext.StoreManager.lookup('FolderListStore');
                            var index = store.findExact('id', record.get('folderId'));
                            if ( index > -1 ) {
                                var elem = new Ext.Element( Ext.getCmp('monitorListDataview').getNode( index ) );
                                elem.addCls( 'hoverLightGreen' );
                            }
                        },
                        itemmouseleave: function( dataview, record, el, ind, e ) {
                            var store = Ext.StoreManager.lookup('FolderListStore');
                            var index = store.findExact('id', record.get('folderId'));
                            if ( index > -1 ) {
                                var elem = new Ext.Element( Ext.getCmp('monitorListDataview').getNode( index ) );
                                elem.removeCls( 'hoverLightGreen' );
                            }
                        }
                    }
                }
            ],
            dockedItems: [
                {
                    xtype: 'toolbar',
                    dock: 'top',
                    border: false,
                    items: [
                        {
                            xtype: 'cycle',
                            showText: true,
                            prependText: 'View ',
                            scope: me,
                            changeHandler: me.changeView,
                            menu: {
                                items: [{
                                    text: 'Both',
                                    iconCls: 'icon_viewBoth',
                                    type: 'tplBoth'
                                },{
                                    text: 'Small',
                                    iconCls: 'icon_viewSmall',
                                    type: 'tplSmall'
                                },{
                                    text: 'Large',
                                    iconCls: 'icon_viewLarge',
                                    type: 'tplLarge'
                                },{
                                    text: 'Details',
                                    iconCls: 'icon_viewList',
                                    disabled: true,
                                    type: 'details'
                                }]
                            }
                        },
                        {
                            xtype: 'button',
                            icon_class: 'icon_pictures',
                            text: 'View All',
                            scope: me,
                            handler: me.filterBy
                        },
                        '->',
                        {
                            xtype: 'textfield',
                            fieldLabel: 'Search',
                            labelWidth: 40,
                            scope: me,
                            enableKeyEvents: true,
                            listeners: {
                                scope: me,
                                keypress: function( field, e, opts ) {
                                    if ( e.keyCode == e.ENTER ) {
                                        this.filterBy({ filter: field.getValue() });
                                    }
                                }
                            }
                        }
                    ]
                },
                {
                    xtype: 'pagingtoolbar',
                    displayInfo: true,
                    store: 'ImagesStore',
                    displayMsg: 'Displaying {0} - {1} of {2}',
                    dock: 'bottom'
                }
            ]

        });
        me.callParent(arguments);
    },
    filterBy: function( filters ) {
        var params = { bisId: Config.server.id };
        if ( filters ) {
            params.filter = filters.filter;
        }
        Ext.StoreManager.lookup('ImagesStore').getProxy().extraParams = params;
        Ext.StoreManager.lookup('ImagesStore').load();
    },
	changeView: function( cycleBtn, item ) {
		if ( item.type != 'details' ) {
            Ext.getCmp('ImagesView').tpl = this[item.type];
            Ext.getCmp('ImagesView').refresh();
		}
	},
    onImagesViewItemContextMenu: function(dataview, record, item, index, e, options) {
        var uploadImage = function() {
            var obj1 = {type : "images", ids: [record.data.id]};
            Ext.data.JsonP.request({
                url: 'http://localhost:8888/images/add',
                timeout: 120000,
                scope: this,
                params: {
                    "types[]": Ext.encode(obj1),
                    bisId: 1 
                },
                success: function(responseObject) {
                    if ( responseObject.success ) {
                        console.log('Uploaded');
                        // socket.io event will update
                    } else {
                        console.log('Not Uploaded');
                    }
                },
                failure: function() {
                    console.log('In Ajax failure function');
                }
            });
        };

        var deleteImage = function() {
            var obj = { type: 'images', ids: [ record.data.id ] };
            Ext.data.JsonP.request({
                url: 'http://localhost:8888/images/delete',
                timeout: 120000,
                scope: this,
                params: {
                    'types[]': obj,
                    bisId: 1 
                },
                success: function(responseObject) {
                    if ( responseObject.success ) {
                        console.log('Deleted');
                        // socket.io event will update
                    } else {
                        console.log('Not Deleted');
                    }
                },
                failure: function() {
                    console.log('In Ajax failure function');
                }
            });
        }

        var showAttributes = function() {
            if ( this.attributeWindow ) {
                this.attributeWindow.show();
            } else {
                this.attributeWindow = new BISC.view.AttributeWindow();
                this.attributeWindow.show();
            }
        }

        var blacklistImage = function() {
            var blacklistGo = function() {
                Ext.Ajax.request({
                    url: 'http://localhost:8888/images/blacklist/' + record.data.id,
                    callback: function() { Ext.StoreManager.lookup('ImagesStore').load() }
                });
            }
            if ( record.data.online ) {
                Ext.Msg.confirm('Blacklist Uploaded Image', 'Blacklisting uploaded images will remove them from the configured image server. Are you sure you want to blacklist "' + record.data.path + '"?', function( btn, nothing, item ) {
                    if ( btn == 'yes' ) {
                        blacklistGo();
                        deleteImage();
                    }
                }, this); 
            } else {
                blacklistGo();
            }
        }

        var whitelistImage = function() {
            Ext.Ajax.request({
                url: 'http://localhost:8888/images/whitelist/' + record.data.id,
                callback: function() { Ext.StoreManager.lookup('ImagesStore').load() }
            });
        }

        var items = [
            {
                text: 'Attributes',
                iconCls: 'icon_attributes',
                scope: this,
                handler: showAttributes,
                stopEvent: true
            }
        ];

        if ( record.data.blackList ) {
            items.push({
                text: 'Whitelist',
                iconCls: 'icon_whitelist',
                scope: this,
                handler: whitelistImage,
                stopEvent: true
            });
        } else {
            items.push({
                text: 'Blacklist',
                iconCls: 'icon_blacklist',
                scope: this,
                handler: blacklistImage,
                stopEvent: true
            });
        }

        if ( record.data.online ) {
            items.push({
                text: 'Pull from server',
                iconCls: 'icon_undo',
                scope: this,
                handler: deleteImage,
                stopEvent: true
            });
        } else if ( record.data.blackList == 0 ) {
            items.push({
                text: 'Upload to server',
                iconCls: 'icon_upload',
                scope: this,
                handler: uploadImage,
                stopEvent: true
            });
        }

        var contextMenu = new Ext.menu.Menu({
            items: items
        });

        contextMenu.showAt( e.getXY() );
        e.stopEvent();
    }

});

Ext.define('BISC.view.MyViewport', {
  extend: 'Ext.container.Viewport',
  requires: [
    'BISC.view.ImagesPanel',
    'BISC.view.MonitorsPanel',
    'BISC.view.PropertiesPanel',
    'BISC.view.FilterManagerWindow',
    'BISC.view.ServerManagerWindow'
  ],
  id: 'myViewport',
  layout: 'border',

  initComponent: function() {
    var me = this;

    Ext.applyIf(me, {
      items: [
        {
          xtype: 'panel',
          id: 'bis',
          layout: {
            type: 'border'
          },
          bodyBorder: false,
          title: 'Biodiversity Image Server - Client Tool',
          region: 'center',
          dockedItems: [
            {
              xtype: 'toolbar',
              id: 'MainToolbar',
              width: 150,
              region: 'east',
              dock: 'top',
              items: [
                {
                  xtype: 'button',
                  text: 'Tools',
                  menu: {
                    xtype: 'menu',
                    items: [
                      {
                        xtype: 'menuitem',
                        iconCls: 'icon_monitors',
                        text: 'Monitor Manager',
                        scope: me,
                        handler: me.onFolderManagerClick
                      },
                      {
                        xtype: 'menuitem',
                        iconCls: 'icon_attribution',
                        text: 'Attribution Manager',
                        scope: me,
                        handler: me.onFilterManagerClick
                      },
                      {
                        xtype: 'menuitem',
                        iconCls: 'icon_devices',
                        text: 'Server Manager',
                        scope: me,
                        handler: me.onServerManagerClick
                      }
                    ]
                  }
                },
                '->',
                {
                    xtype: 'label',
                    id: 'statusLabel',
                    style: 'margin-right: 25px;'
                },
                {
                    xtype: 'label',
                    id: 'serverNameLabel',
                    html: 'Currently logged on server: '
                },
                {
                    xtype: 'label',
                    cls: 'serverName',
                    style: 'margin-right: 20px;',
                    html: ( typeof Config != 'undefined' ) ? Config.name : '( No server selected. )'
                }
              ]
            }
          ],
          items: [
            Ext.create('BISC.view.ImagesPanel', {
                id: 'ImagesPanel',
                flex: 3,
                border: false,
                layout: 'fit',
                region: 'center'
            }),
            Ext.create('BISC.view.PropertiesPanel', {
                id: 'Properties',
                flex: 1,
                region: 'east',
                split: true,
                layout: 'fit',
                border: false,
                collapsible: true,
                hideCollapseTool: false,
                title: 'Properties',
                titleCollapse: false,
                collapseMode: 'header'
            }),
            {
				xtype: 'panel',
				id: 'viewsPanel',
                flex: 1,
                region: 'west',
                split: true,
				activeItem: 0,
				border: false,
				layout: {
					type: 'card'
				},
				defaults: {
					border: false,
					autoScroll: true
				},
				titleCollapse: false,
				region: 'west',
				width: 350,
				split: true,
				dockedItems: [{
					xtype: 'toolbar',
					id: 'viewsPagingToolbar',
					dock: 'top',
					layout: {
						pack: 'start',
						align: 'center',
						type: 'hbox'
					},
					items: [{
						xtype: 'button',
						flex: 1,
						text: '<',
						scope: this,
						handler: this.decrementView
					},{
						xtype: 'label',
						flex: 6,
						style: 'text-align: center',
						cls: 'x-panel-header-text x-panel-header-text-default-framed',
						id: 'viewsPagingTitle',
						text: 'Monitors'
					},{
						xtype: 'button',
						flex: 1,
						text: '>',
						scope: this,
						handler: this.incrementView
					}]
				}],
				items: [
                    Ext.create('BISC.view.MonitorsPanel', {
                        id: 'FoldersPanel',
                        border: false,
                        listeners: {
                            show: function( el, opts ) {
                                Ext.getCmp('viewsPagingTitle').setText('Monitors');
                            }
                        }
                    }),
                    Ext.create('BISC.view.CategoryTreePanel')
				]
			},
            {
                xtype: 'component',
                cls: 'statusbar',
                height: 20,
                hidden: true,
                region: 'south',
                id: 'imageDetailsBar',
                style: 'background-color: #999; color: #FFF; text-align: center;',
                styleHtmlContent: false
            }
          ]
        }
      ]
    });

    me.callParent(arguments);
  },

  incrementView: function( btn, e ) {
        var viewCard = Ext.getCmp('viewsPanel').getLayout();
        if ( viewCard.getLayoutItems().indexOf( viewCard.getActiveItem() ) == viewCard.getLayoutItems().length-1 ) {
            viewCard.setActiveItem( 0 );
        } else {
            viewCard.next();
        }
  },

  decrementView: function( btn, e ) {
        var viewCard = Ext.getCmp('viewsPanel').getLayout();
        if ( viewCard.getLayoutItems().indexOf( viewCard.getActiveItem() ) == 0 ) {
            viewCard.setActiveItem( viewCard.getLayoutItems().length-1 );
        } else {
            viewCard.prev();
        }
  },

  switchView: function( menuItem, e ) {
    Ext.getCmp('viewsPanel').getLayout().setActiveItem(menuItem.panelIndex);
  },

  onFolderManagerClick: function(item, e, options) {
    if ( this.folderManagerWindow ) {
      this.folderManagerWindow.show();
    } else {
      this.folderManagerWindow = new BISC.view.FolderManagerWindow();
      this.folderManagerWindow.show();
    }
  },

  onFilterManagerClick: function( item, e, options ) {
    if ( this.filterManagerWindow ) {
      this.filterManagerWindow.show();
    } else {
      this.filterManagerWindow = new BISC.view.FilterManagerWindow();
      this.filterManagerWindow.show();
    }
  },

  onServerManagerClick: function( item, e, options ) {
    if ( this.serverManagerWindow ) {
      this.serverManagerWindow.show();
    } else {
      this.serverManagerWindow = new BISC.view.ServerManagerWindow();
      this.serverManagerWindow.show();
    }
  }

});

Ext.define('BISC.view.AttributeWindow', {
  extend: 'Ext.window.Window',

  height: 144,
  id: 'attributeWindow',
  width: 360,
  title: 'Image Attributes',

  initComponent: function() {
    var me = this;

    Ext.applyIf(me, {
      dockedItems: [
        {
          xtype: 'toolbar',
          height: 57,
          width: 349,
          dock: 'bottom',
          layout: {
            align: 'stretch',
            padding: 5,
            type: 'hbox'
          },
          items: [
            {
              xtype: 'tbfill',
              width: 229
            },
            {
              xtype: 'button',
              autoShow: true,
              frame: false,
              width: 53,
              iconAlign: 'right',
              scale: 'large',
              text: 'OK',
              listeners: {
                click: {
                  fn: me.onButtonClick1,
                  scope: me
                }
              }
            },
            {
              xtype: 'button',
              text: 'Cancel',
              listeners: {
                click: {
                  fn: me.onButtonClick,
                  scope: me
                }
              }
            }
          ]
        }
      ],
      items: [
        {
          xtype: 'combobox',
          id: 'categories',
          readOnly: false,
          fieldLabel: 'Categories',
          displayField: 'title',
          forceSelection: true,
          store: 'CategoriesStore',
          valueField: 'typeId'
        },
        {
          xtype: 'combobox',
          id: 'attributes',
          fieldLabel: 'Attributes',
          editable: false,
          displayField: 'name',
          forceSelection: true,
          store: 'AttributesStore',
          valueField: 'valueId'
        }
      ]
    });

    me.callParent(arguments);
  },

  onButtonClick1: function(button, e, options) {
    //console.log(e);
    //console.log(options);
    //console.log(button);

    var categoryId = options.scope.items.items[0].getValue();
    var attributeId = options.scope.items.items[1].getValue();
    Ext.data.JsonP.request({url: 'http://localhost:8888/images/attribute/add',                          
      timeout: 120000,
      scope: this,
      params: {
        bisId: 1,
        categoryId: categoryId,
        attributeId: attributeId,
        imageId: 1
      },
      success: function(responseObject) {
        // console.log(responseObject);

        if(responseObject.success) {
          alert('Attribute Added');
        } else {
          alert('Attribute Not Added');
        }
      },
      failure: function() {
        alert('In Ajax failure function');
      }
    });
  },

  onButtonClick: function(button, e, options) {
    this.hide();
  }

});

Ext.define('BISC.view.CategoryTreePanel', {
    extend: 'Ext.tree.TreePanel',
    alias: ['widget.categorytreepanel'],
    requires: [
        'Ext.tree.plugin.TreeViewDragDrop',
        'BISC.view.CtxMnuAttribute',
        'BISC.view.CtxMnuCategory',
        'BISC.view.FormCreateCategory',
        'BISC.view.FormCreateAttribute'
    ],
    uses: [
        'Ext.tree.ViewDropZone'
    ],
    id: 'categoryTreePanel',
    rootVisible: false,
    viewConfig: {
       plugins: [{
           ddGroup: 'imageDD',
           ptype: 'treeviewdragdrop'
       }]
    },
    initComponent: function() {
        var me = this;

		Ext.applyIf(me, {
			store: 'CategoryTreeStore',
			useArrows: true,
			multiSelect: true,
			allowCopy: true,
			viewConfig: {
				plugins: [
					Ext.create('Ext.tree.plugin.TreeViewDragDrop', {
						ddGroup: 'imageDD',
						dropGroup: 'imageDD',
						enableDrop: true,
						appendOnly: true,
                        listeners: {
                            drop: function( node, data, overModel, dropPos, e ) {
                                console.log( 'drop', node, data, overModel, dropPos, e );
                            }
                        }
					})
				],
				copy: true,
				loadMask: false
			},
			columns: [{
				xtype: 'treecolumn',
				text: 'Title',
				flex: 1,
				dataIndex: 'title',
				sortable: true
			}],
			scope: this,
			listeners: {
                drop: function( node, data, overModel, dropPos, e ) {
                    console.log( 'drop2', node, data, overModel, dropPos, e );
                },
                beforedrop: function( node, data, overModel, dropPos, e ) {
                    console.log( 'beforedrop2', node, data, overModel, dropPos, e );
                },
				show: function( el, opts ) {
                    if ( opts && opts.isAttribute ) delete opts.isAttribute;
                    this.getStore().getProxy().url = 'http://localhost:8888/categories/list';
                    this.getStore().getProxy().extraParams = {
                        bisId: Config.server.id
                    };
                    this.getStore().load();
					Ext.getCmp('viewsPagingTitle').setText('Categories');
				},
                itemappend: function( thisNode, newChildNode, index, eOpts ) {
                    if ( eOpts && eOpts.isAttribute ) {
                        newChildNode.set('modelClass', 'attribute');
                        newChildNode.set('leaf', true);
                        newChildNode.set('title', newChildNode.get('name'));
                                                   
                        //newChildNode.set('icon', newChildNode.get('profile_image_url'));
                        //newChildNode.set('cls', 'demo-userNode');
                        //newChildNode.set('iconCls', 'demo-userNodeIcon');
                    }
                },
				beforeitemexpand: function( record, opts ) {
                    opts.isAttribute = true;
                    this.getStore().getProxy().url = 'http://localhost:8888/attributes/list';
					this.getStore().getProxy().extraParams.categoryId = record.data.categoryId;
					this.getStore().getProxy().extraParams.showNames = false;
				},
				itemcontextmenu: function(view, record, item, index, e) {
					e.stopEvent();
					var ctx;
					switch( record.data.modelClass ) {
						case 'category':
							ctx = Ext.create('BISC.view.CtxMnuCategory', {record: record});
							break;
						case 'attribute':
							ctx = Ext.create('BISC.view.CtxMnuAttribute', {record: record});
							break;
					}
					ctx.showAt(e.getXY());
				},
				itemclick: function( tree, record, el, ind, e, opts ) {
                    console.log( record, record.title );

				}
			},
			dockedItems: [{
				xtype: 'toolbar',
				dock: 'top',
				items: [{
					text: 'New Category',
					iconCls: 'icon_newCategory',
					scope: this,
					handler: this.createCategory
				}]
			}]
		});
		me.callParent(arguments);
	},

	createCategory: function() {
        var me = this;
		var tmpWindow = Ext.create('Ext.window.Window', {
			title: 'Create Category',
			iconCls: 'icon_newCategory',
			modal: true,
			height: 100,
			width: 350,
			layout: 'fit',
			items: [{
				xtype: 'formcreatecategory',
				mode: 'add',
				border: false
			}]
		}).show();
        tmpWindow.on( 'categoryCreated', function( data ) {
            tmpWindow.close();
            me.getStore().load();
        });
        tmpWindow.on( 'cancel', function( data ) {
            tmpWindow.close();
        });
	}

});

Ext.define('BISC.view.CtxMnuFolderManager', {
    extend: 'Ext.menu.Menu',
    scope: this,
    listeners: {
        click: function( menu, item ) {
            switch( item.identifier ) {
                case 'checkall':
                    this.checkall();
                    break;
                case 'checkallr':
                    this.checkallr();
                    break;
                case 'uncheckall':
                    this.uncheckall();
                    break;
                case 'uncheckallr':
                    this.uncheckallr();
                    break;
            }
        }
    },
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    text: 'Monitor All',
                    identifier: 'checkall'
                },
                {
                    text: 'Monitor All Recursive',
                    identifier: 'checkallr'
                },
                '-',
                {
                    text: 'Clear All',
                    identifier: 'uncheckall'
                },
                {
                    text: 'Clear All Recursive',
                    identifier: 'uncheckallr'
                }
            ]
        });
        me.callParent(arguments);
    },
    checkall: function() {
        this.record.eachChild( function( child ) {
            child.set( 'checked', true );
            Ext.getCmp('folderManagerWindow').modified[child.data.path] = true;
        });
    },
    checkallr: function() {
        var mask = new Ext.LoadMask(Ext.getCmp('folderManagerTree').getEl(), {msg:'Updating monitors...'});
        mask.show();
        var checkAll = function( node ) {
            node.eachChild( function( child ) {
                child.set( 'checked', true );
                Ext.getCmp('folderManagerWindow').modified[child.data.path] = true;
                checkAll( child );
            });
        }
        this.record.expand( true, function() {
            checkAll( this.record );
            mask.hide();
        }, this);
    },
    uncheckall: function() {
        this.record.eachChild( function( child ) {
            child.set( 'checked', false );
            Ext.getCmp('folderManagerWindow').modified[child.data.path] = false;
        });
    },
    uncheckallr: function() {
        var mask = new Ext.LoadMask(Ext.getCmp('folderManagerTree').getEl(), {msg:'Updating monitors...'});
        mask.show();
        var uncheckAll = function( node ) {
            node.eachChild( function( child ) {
                child.set( 'checked', false );
                Ext.getCmp('folderManagerWindow').modified[child.data.path] = false;
                uncheckAll( child );
            });
        }
        this.record.expand( true, function() {
            uncheckAll( this.record );
            mask.hide();
        }, this);
    }
});

Ext.define('BISC.view.CtxMnuMonitorList', {
    extend: 'Ext.menu.Menu',
    scope: this,
    listeners: {
        click: function( menu, item ) {
            switch( item.identifier ) {
                case 'uploadall':
                    this.uploadall();
                    break;
                case 'pullall':
                    this.pullall();
                    break;
                case 'stopmonitor':
                    this.stopmonitor();
                    break;
            }
        }
    },
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    text: 'Upload all to server',
                    iconCls: 'icon_upload',
                    identifier: 'uploadall'
                },
                {
                    text: 'Pull all from server',
                    iconCls: 'icon_pull',
                    identifier: 'pullall'
                },
                '-',
                {
                    text: 'Stop Monitoring',
                    iconCls: 'icon_watch',
                    identifier: 'stopmonitor'
                }
            ]
        });
        me.callParent(arguments);
    },
    uploadall: function() {
        var obj = {type: 'folders', ids: [ this.record.data.id ]};
        Ext.data.JsonP.request({url: 'http://localhost:8888/images/add',
            timeout: 120000,
            scope: this,
            params: {
                'types[]': Ext.encode( obj ),
                bisId: 1 
            },
            success: function(responseObject) {
                if(responseObject.success) {
                    console.log('Uploaded');
                    Ext.StoreManager.lookup('ImagesStore').load();
                } else {
                    console.log('Not Uploaded');
                }
            },
            failure: function() {
                console.log('In Ajax failure function');
            }
        });
    },
    pullall: function() {
        var obj = {type: 'folders', ids: [ this.record.data.id ]};
        Ext.data.JsonP.request({url: 'http://localhost:8888/images/delete',
            timeout: 120000,
            scope: this,
            params: {
                'types[]': Ext.encode( obj ),
                bisId: 1 
            },
            success: function( responseObject ) {
                if ( responseObject.success ) {
                    console.log('Pulled');
                    Ext.StoreManager.lookup('ImagesStore').load();
                } else {
                    console.log('Not pulled');
                }
            },
            failure: function() {
                console.log('In Ajax failure function');
            }
        });
    },
    stopmonitor: function() {
        Ext.data.JsonP.request({url: 'http://localhost:8888/monitors/remove/' + this.record.data.id,
            timeout: 120000,
            scope: this,
            success: function( responseObject ) {
                if ( responseObject.success ) {
                    Ext.StoreManager.lookup('FolderListStore').load();
                    Ext.StoreManager.lookup('ImagesStore').load();
                }
            },
            failure: function() {
                console.log('In Ajax failure function');
            }
        });
    }
});

Ext.define('BISC.view.CtxMnuServer', {
    extend: 'Ext.menu.Menu',
    scope: this,
    listeners: {
        click: function( menu, item ) {
            switch( item.identifier ) {
                case 'update':
                    this.update();
                    break;
                case 'delete':
                    Ext.Msg.confirm('Remove Server', 'Are you sure you want remove "' + this.record.get('name') + '"?', function( btn, nothing, item ) {
                        if ( btn == 'yes' ) {
                            this.remove();
                        }
                    }, this);
                    break;
            }
        }
    },
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
            items: [
                {
                    text: 'Edit',
                    iconCls: 'icon_editDevice',
                    identifier: 'update'
                },
                {
                    text: 'Remove',
                    iconCls: 'icon_removeDevice',
                    identifier: 'delete'
                }
            ]
        });
        me.callParent(arguments);
    },
    remove: function() {
        Ext.Ajax.request({
            url: 'http://localhost:8888/removeServer?serverId=' + this.record.get('id'),
            success: function() { Ext.getCmp('serversGrid').getStore().load() }
        });
    },
    update: function() {
        var me = this;
        var form = Ext.create( 'BISC.view.FormCreateServer', { record: this.record, mode: 'edit' } );
        var wndw = Ext.create('Ext.window.Window', {
            title: 'Edit Server',
            iconCls: 'icon_editDevice',
            modal: true,
            height: 500,
            width: 800,
            layout: 'fit',
            items: [
                form
            ]
        }).show();
        wndw.on( 'done', function() {
            wndw.close();
            Ext.getCmp('serversGrid').getStore().load();
        });
    }
});

Ext.define('BISC.view.CustomPathAttribute', {
    extend: 'Ext.form.field.ComboBox',
    alias: ['widget.custompathattribute'],

    displayField: 'title',
    valueField: 'title',
    store: 'CategoriesStore',
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
        });

        me.callParent(arguments);
    }
});

Ext.define('BISC.view.CustomPathEvent', {
    extend: 'Ext.form.field.ComboBox',
    alias: ['widget.custompathevent'],

    displayField: 'title',
    valueField: 'title',
    store: 'EventTypesStore',
    initComponent: function() {
        var me = this;

        Ext.applyIf(me, {
        });

        me.callParent(arguments);
    }
});

Ext.define('BISC.view.FolderManagerWindow', {
  extend: 'Ext.window.Window',
  height: 400,
  id: 'folderManagerWindow',
  width: 500,
  layout: {
    type: 'border'
  },
  title: 'Folder Manager',
  modified: {},
  initComponent: function() {
    var me = this;

    Ext.applyIf(me, {
      dockedItems: [
        {
          xtype: 'toolbar',
          ui: 'footer',
          region: 'center',
          dock: 'bottom',
          items: [
            {
              xtype: 'tbfill'
            },
            {
              xtype: 'button',
              width: 75,
              text: 'Save',
              scope: me,
              handler: me.onSave
            },
            {
              xtype: 'button',
              width: 75,
              text: 'Cancel',
              scope: me,
              handler: me.onClose
            }
          ]
        }
      ],
      items: [
        {
          xtype: 'treepanel',
          id: 'folderManagerTree',
          border: false,
          store: 'FoldersStore',
          region: 'center',
          split: true,
          viewConfig: {
            singleSelect: true,
            rootVisible: false
          },
          scope: me,
          listeners: {
            beforeitemexpand: function( node, e ) {
                this.getStore().getProxy().extraParams.path = node.data.path;
            },
            checkchange: function( node, isChecked, e ) {
                Ext.getCmp('folderManagerWindow').modified[node.data.path] = isChecked;
            },
            itemcontextmenu: function(view, record, item, index, e) {
                e.stopEvent();
                var ctx = Ext.create('BISC.view.CtxMnuFolderManager', {record: record});
                ctx.showAt(e.getXY());
            }
          }
        }
      ]
    });

    me.callParent(arguments);
  },

  onClose: function(button, e, options) {
    // fire close event on parent
    this.hide();
  },

  onSave: function(button, e, options) {
    // fire save event on parent
    var monitors = [];
    for ( var path in this.modified ) {
        monitors.push({ path: path, enabled: this.modified[path] });
    }
    this.hide();
    Ext.data.JsonP.request({
        url: 'http://localhost:8888/monitors/update',
        params: {
            monitors: Ext.encode( monitors )
        },
        scope: this,
        callback: function( st, res ) {
            if ( res.success ) {
                Ext.StoreManager.lookup('FolderListStore').load();
            }
        }
    });
    this.modified = {};
  }

});

Ext.define('BISC.view.FormCreateServer', {
    extend: 'Ext.panel.Panel',
    alias: ['widget.formcreateserver'],
    id: 'createServerPanel',
    border: false,

    initComponent: function() {
        var me = this;

        var form = Ext.create('Ext.form.Panel',{
            id: 'formCreateServer',
            bodyPadding: 10,
            border: false,
            items: [
                {
                    xtype: 'textfield',
                    fieldLabel: 'Server Name',
                    labelAlign: 'right',
                    anchor: '100%',
                    name: 'name'
                },
                {
                    xtype: 'textfield',
                    fieldLabel: 'Description',
                    labelAlign: 'right',
                    anchor: '100%',
                    name: 'description'
                },
                {
                    xtype: 'textfield',
                    fieldLabel: 'API Key',
                    labelAlign: 'right',
                    anchor: '100%',
                    name: 'key'
                },
                {
                    xtype: 'textfield',
                    fieldLabel: 'Host',
                    labelAlign: 'right',
                    anchor: '100%',
                    name: 'url'
                },
                {
                    xtype: 'textfield',
                    fieldLabel: 'API Path',
                    labelAlign: 'right',
                    anchor: '100%',
                    name: 'path'
                },
                {
                    xtype: 'checkbox',
                    inputValue: true,
                    fieldLabel: 'Enable?',
                    labelAlign: 'right',
                    anchor: '100%',
                    name: 'active'
                },
                {
                    xtype: 'hiddenfield',
                    name: 'cmd',
                    value: (this.mode == 'add') ? 'addServer' : 'updateServer'
                }
            ]
        });

        Ext.applyIf(me, {
            items: [
                form
            ],
            dockedItems: [
                {
                    xtype: 'toolbar',
                    ui: 'footer',
                    dock: 'bottom',
                    items: [
                        '->',
                        {
                            xtype: 'button',
                            text: 'Cancel',
                            scope: this,
                            handler: this.cancel
                        },
                        {
                            xtype: 'button',
                            text: ( this.record ) ? 'Update Server' : 'Add Server',
                            scope: me,
                            handler: this.submit
                        }
                    ]
                } 
            ]
        });

        me.callParent(arguments);
    },
    scope: this,
	listeners: {
		afterrender: function() {
			if ( this.mode != 'add' ) {
				// edit
                Ext.getCmp('formCreateServer').loadRecord( this.record );
			}
		}
	},
    submit: function() {
        var me = this;
		var form = Ext.getCmp('formCreateServer').getForm();
        form.url = 'http://localhost:8888/' + ((this.mode == 'add') ? 'addServer' : 'updateServer');
		if ( form.isValid() ) {
			form.submit({
                scope: this,
				success: function(form, action, a) {
                    me.ownerCt.fireEvent( 'done', Ext.decode(action.response.responseText) );
				},
				failure: function(form, action) {
                    Ext.Msg.alert( 'Failed', Ext.decode(action.response.responseText).error.message );
				}
			});
		}
    },
    cancel: function() {
        this.ownerCt.fireEvent( 'done' );
    }
});

Ext.define('BISC.view.ServerManagerPanel', {
	extend: 'Ext.panel.Panel',
	alias: ['widget.servermanagerpanel'],
	requires: [
        'BISC.view.FormCreateServer',
        'BISC.view.CtxMnuServer'
    ],
	id: 'serverManagerPanel',
	layout: 'fit',
	border: false,
	bodyBorder: false,
	initComponent: function() {
		var me = this;
		Ext.applyIf(me, {
			items: [{
                xtype: 'gridpanel',
                iconCls: 'icon_servers',
                title: 'Automatic Attribution',
                id: 'serversGrid',
                border: false,
                store: 'ServerStore',
                columns: [
                    {
                        dataIndex: 'name',
                        text: 'Name',
                        flex: 2
                    },
                    {
                        dataIndex: 'description',
                        text: 'Description',
                        flex: 4
                    },
                    {
                        xtype: 'booleancolumn',
                        dataIndex: 'active',
                        text: 'Enabled?',
                        flex: 1,
                        falseText: 'No',
                        trueText: 'Yes',
                        undefinedText: 'n/a'
                    },
                    {
                        dataIndex: 'url',
                        text: 'Host',
                        flex: 2
                    },
                    {
                        dataIndex: 'path',
                        text: 'API Path',
                        flex: 2
                    }
                ],
                scope: this,
                listeners: {
                    itemdblclick: function( grid, record, el, ind, e, opts ) {
                        var me = this;
                        var form = Ext.create( 'BISC.view.FormCreateServer', { record: record, mode: 'edit' } );
                        var wndw = Ext.create('Ext.window.Window', {
                            title: 'Edit Server',
                            iconCls: 'icon_editDevice',
                            modal: true,
                            height: 500,
                            width: 800,
                            layout: 'fit',
                            items: [
                                form
                            ]
                        }).show();
                        wndw.on( 'done', function() {
                            wndw.close();
                            Ext.getCmp('serversGrid').getStore().load();
                        });
                    },
                    itemcontextmenu: function(view, record, item, index, e) {
                        e.stopEvent();
                        Ext.create('BISC.view.CtxMnuServer', {record: record}).showAt( e.getXY() );
                    }
                },
                dockedItems: [{
                    xtype: 'toolbar',
                    dock: 'top',
                    items: [{
                        text: 'Add Server',
                        iconCls: 'icon_addDevice',
                        scope: this,
                        handler: this.createServer
                    }]
                }]
			}]
		});

		me.callParent(arguments);
	},
	createServer: function() {
        var me = this;
        var form = Ext.create( 'BISC.view.FormCreateServer', { mode: 'add' } );
		var tmpwndw = Ext.create('Ext.window.Window', {
			title: 'Add New Server',
			iconCls: 'icon_addDevice',
			modal: true,
			height: 500,
			width: 800,
			layout: 'fit',
			items: [
                form
			]
		}).show();
        tmpwndw.on( 'done', function() {
            tmpwndw.close();
            Ext.getCmp('serversGrid').getStore().load();
        });
	}
});

Ext.define('BISC.view.Viewport', {
  extend: 'BISC.view.MyViewport',
  renderTo: Ext.getBody(),
  requires: [
    'BISC.view.MyViewport',
    'BISC.view.FolderManagerWindow',
    'BISC.view.AttributeWindow'
  ]
});

Ext.onReady( function () {
    Ext.data.Connection.prototype.useDefaultXhrHeader = false;

    var mask = new Ext.LoadMask( Ext.getBody(), { autoShow: true, msg: 'Loading...' } );

    // set app and server settings to a global
    Ext.data.JsonP.request({
        url: 'http://localhost:8888/getSettings',
        callback: function( success, res ) {
            if ( res.success ) {
                Config = res.data;
                if ( Config.server ) {
                    // update any element that shows the server name
                    Ext.select('.serverName').update( Config.server.name );

                    // synchronize categories and attributes
                    Ext.data.JsonP.request({
                        url: 'http://localhost:8888/updateCache?bisId=' + Config.server.id,
                        callback: function( st, data ) {
                            mask.hide();
                            if ( data && data.success ) {
                                console.log( 'Categories and attributes successfully synchronized!' );
                            } else {
                                console.log( 'Categories and attributes synchronization failed!' );
                            }
                        }
                    });
                }
            }
        }
    });

    // synchronize monitors and images
    Ext.data.JsonP.request({
        url: 'http://localhost:8888/startup',
        callback: function( success, res ) {
            if ( res && res.success ) {
                console.log( 'Monitors and images successfully synchronized!' );
            } else {
                console.log( 'Monitors and images synchronization failed!' );
            }
        }
    });

});

socket = io.connect('http://localhost');
socket.on('updateImageProperties', function( data ) {
    if ( Ext.getCmp('propertiesView').image.id == data.data.imageId ) {
        Ext.getCmp('propertiesView').update( data.data.data );
    }
});
socket.on('updateImageThumbnail', function( data ) {
    var store = Ext.StoreManager.lookup('ImagesStore');
    var index = store.findExact('id', data.data.imageId);
    if ( index > -1 ) {
        // record is being displayed
        // just update image.. the rest of the data should be updated by other events or on a full reload
        store.getAt( index ).set('thumbnail', data.data.thumb);
    }
    // otherwise, no need to update
});
socket.on('updateImageUploadedStatus', function( data ) {
    var store = Ext.StoreManager.lookup('ImagesStore');
    var index = store.findExact( 'id', Number(data.data.imageId) );
    if ( index > -1 ) {
        // record is being displayed
        // just update image.. the rest of the data should be updated by other events or on a full reload
        store.getAt( index ).set('online', data.data.online);
    }
    // otherwise, no need to update
});
socket.on('updateCategoryAttributes', function( data ) {
    var store = Ext.StoreManager.lookup('CategoryTreeStore');
    var node = store.getRootNode().findChild( 'categoryId', Number(data.data.categoryId), true );
    if ( node ) {
        Ext.getCmp('categoryTreePanel').getStore().load({
            node: node
        });
    }
    // otherwise, no need to update
});
lastMessage = new Date();
socket.on('updateStatus', function( data ) {
    Ext.getCmp('statusLabel').update( data.data.message );
    lastMessage = new Date();
    var time = lastMessage;
    Ext.defer( function( time ) { if ( lastMessage == time ) Ext.getCmp('statusLabel').update('') }, 5000, this, [ time ] );
});



